diff --git a/.github/ci-cd-scripts/playwright-electron.sh b/.github/ci-cd-scripts/playwright-electron.sh index d45556ba2..f5c5acc2b 100755 --- a/.github/ci-cd-scripts/playwright-electron.sh +++ b/.github/ci-cd-scripts/playwright-electron.sh @@ -4,27 +4,27 @@ set -euo pipefail if [[ ! -f "test-results/.last-run.json" ]]; then - # if no last run artifact, than run plawright normally + # If no last run artifact, than run Playwright normally echo "run playwright normally" - if [[ "$3" == *ubuntu* ]]; then - xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- yarn test:playwright:electron:ubuntu -- --shard=$1/$2 || true - elif [[ "$3" == *windows* ]]; then - yarn test:playwright:electron:windows -- --shard=$1/$2 || true - elif [[ "$3" == *macos* ]]; then - yarn test:playwright:electron:macos -- --shard=$1/$2 || true - else - echo "Do not run playwright. Unable to detect os runtime." - exit 1 - fi - # # send to axiom - node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1 + if [[ "$3" == *ubuntu* ]]; then + xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- yarn test:playwright:electron:ubuntu -- --shard=$1/$2 || true + elif [[ "$3" == *windows* ]]; then + yarn test:playwright:electron:windows -- --shard=$1/$2 || true + elif [[ "$3" == *macos* ]]; then + yarn test:playwright:electron:macos -- --shard=$1/$2 || true + else + echo "Do not run Playwright. Unable to detect os runtime." + exit 1 + fi + # Log failures for Axiom to pick up + node playwrightProcess.mjs > /tmp/github-actions.log fi retry=1 -max_retrys=1 +max_retries=1 -# retry failed tests, doing our own retries because using inbuilt playwright retries causes connection issues -while [[ $retry -le $max_retrys ]]; do +# Retry failed tests, doing our own retries because using inbuilt Playwright retries causes connection issues +while [[ $retry -le $max_retries ]]; do if [[ -f "test-results/.last-run.json" ]]; then failed_tests=$(jq '.failedTests | length' test-results/.last-run.json) if [[ $failed_tests -gt 0 ]]; then @@ -40,8 +40,8 @@ while [[ $retry -le $max_retrys ]]; do echo "Do not run playwright. Unable to detect os runtime." exit 1 fi - # send to axiom - node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1 + # Log failures for Axiom to pick up + node playwrightProcess.mjs > /tmp/github-actions.log retry=$((retry + 1)) else echo "retried=false" >>$GITHUB_OUTPUT @@ -58,7 +58,7 @@ echo "retried=false" >>$GITHUB_OUTPUT if [[ -f "test-results/.last-run.json" ]]; then failed_tests=$(jq '.failedTests | length' test-results/.last-run.json) if [[ $failed_tests -gt 0 ]]; then - # if it still fails after 3 retrys, then fail the job + # If it still fails after 3 retries, then fail the job exit 1 fi fi diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index da76f27b5..d9b187bdb 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -340,14 +340,22 @@ jobs: if: needs.conditions.outputs.should-run == 'true' run: yarn tronb:vite:dev - - name: Install good sed - if: startsWith(matrix.os, 'macos') + - name: Install vector + if: contains(matrix.os, 'ubuntu') shell: bash run: | - brew install gnu-sed - echo "/opt/homebrew/opt/gnu-sed/libexec/gnubin" >> $GITHUB_PATH - - # TODO: Add back axiom logs + curl --proto '=https' --tlsv1.2 -sSfL https://sh.vector.dev > /tmp/vector.sh + chmod +x /tmp/vector.sh + /tmp/vector.sh -y -no-modify-path + mkdir -p /tmp/vector + cp .github/workflows/vector.toml /tmp/vector.toml + sed -i "s#GITHUB_WORKFLOW#${GITHUB_WORKFLOW}#g" /tmp/vector.toml + sed -i "s#GITHUB_REPOSITORY#${GITHUB_REPOSITORY}#g" /tmp/vector.toml + sed -i "s#GITHUB_SHA#${GITHUB_SHA}#g" /tmp/vector.toml + sed -i "s#GITHUB_REF_NAME#${GITHUB_REF_NAME}#g" /tmp/vector.toml + sed -i "s#GH_ACTIONS_AXIOM_TOKEN#${{secrets.GH_ACTIONS_AXIOM_TOKEN}}#g" /tmp/vector.toml + cat /tmp/vector.toml + ${HOME}/.vector/bin/vector --config /tmp/vector.toml & - uses: actions/download-artifact@v4 if: ${{ needs.conditions.outputs.should-run == 'true' && !cancelled() && (success() || failure()) }} diff --git a/e2e/playwright/basic-sketch.spec.ts b/e2e/playwright/basic-sketch.spec.ts index 578e7e7ef..f80b18f6f 100644 --- a/e2e/playwright/basic-sketch.spec.ts +++ b/e2e/playwright/basic-sketch.spec.ts @@ -153,7 +153,8 @@ async function doBasicSketch( } test.describe('Basic sketch', { tag: ['@skipWin'] }, () => { - test.fixme('code pane open at start', async ({ page, homePage }) => { + test('code pane open at start', async ({ page, homePage }) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') await doBasicSketch(page, homePage, ['code']) }) diff --git a/e2e/playwright/code-pane-and-errors.spec.ts b/e2e/playwright/code-pane-and-errors.spec.ts index 2b62ea0d6..91fcd8210 100644 --- a/e2e/playwright/code-pane-and-errors.spec.ts +++ b/e2e/playwright/code-pane-and-errors.spec.ts @@ -46,11 +46,12 @@ test.describe('Code pane and errors', { tag: ['@skipWin'] }, () => { await expect(codePaneButtonHolder).toContainText('notification') }) - test.skip('Opening and closing the code pane will consistently show error diagnostics', async ({ + test('Opening and closing the code pane will consistently show error diagnostics', async ({ page, homePage, editor, }) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') const u = await getUtils(page) // Load the app with the working starter code @@ -119,45 +120,47 @@ test.describe('Code pane and errors', { tag: ['@skipWin'] }, () => { await expect(page.locator('.cm-tooltip').first()).toBeVisible() }) - test.fixme( - 'When error is not in view you can click the badge to scroll to it', - async ({ page, homePage, context }) => { - // Load the app with the working starter code - await context.addInitScript((code) => { - localStorage.setItem('persistCode', code) - }, TEST_CODE_LONG_WITH_ERROR_OUT_OF_VIEW) + test('When error is not in view you can click the badge to scroll to it', async ({ + page, + homePage, + context, + }) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') + // Load the app with the working starter code + await context.addInitScript((code) => { + localStorage.setItem('persistCode', code) + }, TEST_CODE_LONG_WITH_ERROR_OUT_OF_VIEW) - await page.setBodyDimensions({ width: 1200, height: 500 }) - await homePage.goToModelingScene() + await page.setBodyDimensions({ width: 1200, height: 500 }) + await homePage.goToModelingScene() - await page.waitForTimeout(1000) + await page.waitForTimeout(1000) - // Ensure badge is present - const codePaneButtonHolder = page.locator('#code-button-holder') - await expect(codePaneButtonHolder).toContainText('notification') + // Ensure badge is present + const codePaneButtonHolder = page.locator('#code-button-holder') + await expect(codePaneButtonHolder).toContainText('notification') - // Ensure we have no errors in the gutter, since error out of view. - await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible() + // Ensure we have no errors in the gutter, since error out of view. + await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible() - // Click the badge. - const badge = page.locator('#code-badge') - await expect(badge).toBeVisible() - await badge.click() + // Click the badge. + const badge = page.locator('#code-badge') + await expect(badge).toBeVisible() + await badge.click() - // Ensure we have an error diagnostic. - await expect(page.locator('.cm-lint-marker-error').first()).toBeVisible() + // Ensure we have an error diagnostic. + await expect(page.locator('.cm-lint-marker-error').first()).toBeVisible() - // Hover over the error to see the error message - await page.hover('.cm-lint-marker-error') - await expect( - page - .getByText( - 'Modeling command failed: [ApiError { error_code: InternalEngine, message: "Solid3D revolve failed: sketch profile must lie entirely on one side of the revolution axis" }]' - ) - .first() - ).toBeVisible() - } - ) + // Hover over the error to see the error message + await page.hover('.cm-lint-marker-error') + await expect( + page + .getByText( + 'Modeling command failed: [ApiError { error_code: InternalEngine, message: "Solid3D revolve failed: sketch profile must lie entirely on one side of the revolution axis" }]' + ) + .first() + ).toBeVisible() + }) test('When error is not in view WITH LINTS you can click the badge to scroll to it', async ({ context, diff --git a/e2e/playwright/command-bar-tests.spec.ts b/e2e/playwright/command-bar-tests.spec.ts index 4db44bdbe..2c6195fd4 100644 --- a/e2e/playwright/command-bar-tests.spec.ts +++ b/e2e/playwright/command-bar-tests.spec.ts @@ -47,7 +47,8 @@ test.describe('Command bar tests', { tag: ['@skipWin'] }, () => { }) // TODO: fix this test after the electron migration - test.fixme('Fillet from command bar', async ({ page, homePage }) => { + test('Fillet from command bar', async ({ page, homePage }) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') await page.addInitScript(async () => { localStorage.setItem( 'persistCode', diff --git a/e2e/playwright/editor-tests.spec.ts b/e2e/playwright/editor-tests.spec.ts index 7ded79e2d..6f6df4882 100644 --- a/e2e/playwright/editor-tests.spec.ts +++ b/e2e/playwright/editor-tests.spec.ts @@ -635,14 +635,16 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => { await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible() }) - test.fixme( - 'error with 2 source ranges gets 2 diagnostics', - async ({ page, homePage }) => { - const u = await getUtils(page) - await page.addInitScript(async () => { - localStorage.setItem( - 'persistCode', - `length = .750 + test('error with 2 source ranges gets 2 diagnostics', async ({ + page, + homePage, + }) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') + const u = await getUtils(page) + await page.addInitScript(async () => { + localStorage.setItem( + 'persistCode', + `length = .750 width = 0.500 height = 0.500 dia = 4 @@ -657,53 +659,52 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => { return squareHoleSketch } ` - ) - }) - await page.setBodyDimensions({ width: 1000, height: 500 }) + ) + }) + await page.setBodyDimensions({ width: 1000, height: 500 }) - await homePage.goToModelingScene() - await u.waitForPageLoad() - await page.waitForTimeout(1000) + await homePage.goToModelingScene() + await u.waitForPageLoad() + await page.waitForTimeout(1000) - await u.openDebugPanel() - await u.expectCmdLog('[data-message-type="execution-done"]') - await u.closeDebugPanel() + await u.openDebugPanel() + await u.expectCmdLog('[data-message-type="execution-done"]') + await u.closeDebugPanel() - // check no error to begin with - await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible() + // check no error to begin with + await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible() - // Click on the bottom of the code editor to add a new line - await u.codeLocator.click() - await page.keyboard.press('ArrowDown') - await page.keyboard.press('ArrowDown') - await page.keyboard.press('ArrowDown') - await page.keyboard.press('ArrowDown') - await page.keyboard.press('ArrowDown') - await page.keyboard.press('ArrowDown') - await page.keyboard.press('ArrowDown') - await page.keyboard.press('ArrowDown') - await page.keyboard.press('ArrowDown') - await page.keyboard.press('ArrowDown') - await page.keyboard.press('ArrowDown') - await page.keyboard.press('ArrowDown') - await page.keyboard.press('ArrowDown') - await page.keyboard.press('Enter') - await page.keyboard.type(`extrusion = startSketchOn('XY') + // Click on the bottom of the code editor to add a new line + await u.codeLocator.click() + await page.keyboard.press('ArrowDown') + await page.keyboard.press('ArrowDown') + await page.keyboard.press('ArrowDown') + await page.keyboard.press('ArrowDown') + await page.keyboard.press('ArrowDown') + await page.keyboard.press('ArrowDown') + await page.keyboard.press('ArrowDown') + await page.keyboard.press('ArrowDown') + await page.keyboard.press('ArrowDown') + await page.keyboard.press('ArrowDown') + await page.keyboard.press('ArrowDown') + await page.keyboard.press('ArrowDown') + await page.keyboard.press('ArrowDown') + await page.keyboard.press('Enter') + await page.keyboard.type(`extrusion = startSketchOn('XY') |> circle(center: [0, 0], radius: dia/2) |> hole(squareHole(length, width, height), %) |> extrude(length = height)`) - // error in gutter - await expect(page.locator('.cm-lint-marker-error').first()).toBeVisible() - await page.hover('.cm-lint-marker-error:first-child') - await expect( - page.getByText('Expected 2 arguments, got 3').first() - ).toBeVisible() + // error in gutter + await expect(page.locator('.cm-lint-marker-error').first()).toBeVisible() + await page.hover('.cm-lint-marker-error:first-child') + await expect( + page.getByText('Expected 2 arguments, got 3').first() + ).toBeVisible() - // Make sure there are two diagnostics - await expect(page.locator('.cm-lint-marker-error')).toHaveCount(2) - } - ) + // Make sure there are two diagnostics + await expect(page.locator('.cm-lint-marker-error')).toHaveCount(2) + }) test('if your kcl gets an error from the engine it is inlined', async ({ context, page, @@ -1121,10 +1122,11 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => { } ) - test.fixme( + test( `Can use the import stdlib function on a local OBJ file`, { tag: '@electron' }, async ({ page, context }, testInfo) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') await context.folderSetupFn(async (dir) => { const bracketDir = join(dir, 'cube') await fsp.mkdir(bracketDir, { recursive: true }) diff --git a/e2e/playwright/file-tree.spec.ts b/e2e/playwright/file-tree.spec.ts index ca08f3a90..1e90d485f 100644 --- a/e2e/playwright/file-tree.spec.ts +++ b/e2e/playwright/file-tree.spec.ts @@ -266,12 +266,13 @@ test.describe('when using the file tree to', () => { } ) - test.fixme( + test( 'loading small file, then large, then back to small', { tag: '@electron', }, async ({ page }, testInfo) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') const { panesOpen, pasteCodeInEditor, diff --git a/e2e/playwright/onboarding-tests.spec.ts b/e2e/playwright/onboarding-tests.spec.ts index 8be152a44..7a0e80516 100644 --- a/e2e/playwright/onboarding-tests.spec.ts +++ b/e2e/playwright/onboarding-tests.spec.ts @@ -319,237 +319,240 @@ test.describe('Onboarding tests', () => { // (lee) The two avatar tests are weird because even on main, we don't have // anything to do with the avatar inside the onboarding test. Due to the // low impact of an avatar not showing I'm changing this to fixme. - test.fixme( - 'Avatar text updates depending on image load success', - async ({ context, page, homePage, tronApp }) => { - if (!tronApp) { - fail() - } - - await tronApp.cleanProjectDir({ - app: { - onboarding_status: '', - }, - }) - - // Override beforeEach test setup - await context.addInitScript( - async ({ settingsKey, settings }) => { - localStorage.setItem(settingsKey, settings) - }, - { - settingsKey: TEST_SETTINGS_KEY, - settings: settingsToToml({ - settings: TEST_SETTINGS_ONBOARDING_USER_MENU, - }), - } - ) - - await page.setBodyDimensions({ width: 1200, height: 500 }) - await homePage.goToModelingScene() - - // Test that the text in this step is correct - const avatarLocator = page - .getByTestId('user-sidebar-toggle') - .locator('img') - const onboardingOverlayLocator = page - .getByTestId('onboarding-content') - .locator('div') - .nth(1) - - // Expect the avatar to be visible and for the text to reference it - await expect(avatarLocator).toBeVisible() - await expect(onboardingOverlayLocator).toBeVisible() - await expect(onboardingOverlayLocator).toContainText('your avatar') - - // This is to force the avatar to 404. - // For our test image (only triggers locally. on CI, it's Kurt's / - // gravatar image ) - await page.route('/cat.jpg', async (route) => { - await route.fulfill({ - status: 404, - contentType: 'text/plain', - body: 'Not Found!', - }) - }) - - // 404 the CI avatar image - await page.route( - 'https://lh3.googleusercontent.com/**', - async (route) => { - await route.fulfill({ - status: 404, - contentType: 'text/plain', - body: 'Not Found!', - }) - } - ) - - await page.reload({ waitUntil: 'domcontentloaded' }) - - // Now expect the text to be different - await expect(avatarLocator).not.toBeVisible() - await expect(onboardingOverlayLocator).toBeVisible() - await expect(onboardingOverlayLocator).toContainText('the menu button') - } - ) - - test.fixme( - "Avatar text doesn't mention avatar when no avatar", - async ({ context, page, homePage, tronApp }) => { - if (!tronApp) { - fail() - } - - await tronApp.cleanProjectDir({ - app: { - onboarding_status: '', - }, - }) - // Override beforeEach test setup - await context.addInitScript( - async ({ settingsKey, settings }) => { - localStorage.setItem(settingsKey, settings) - localStorage.setItem('FORCE_NO_IMAGE', 'FORCE_NO_IMAGE') - }, - { - settingsKey: TEST_SETTINGS_KEY, - settings: settingsToToml({ - settings: TEST_SETTINGS_ONBOARDING_USER_MENU, - }), - } - ) - - await page.setBodyDimensions({ width: 1200, height: 500 }) - await homePage.goToModelingScene() - - // Test that the text in this step is correct - const sidebar = page.getByTestId('user-sidebar-toggle') - const avatar = sidebar.locator('img') - const onboardingOverlayLocator = page - .getByTestId('onboarding-content') - .locator('div') - .nth(1) - - // Expect the avatar to be visible and for the text to reference it - await expect(avatar).not.toBeVisible() - await expect(onboardingOverlayLocator).toBeVisible() - await expect(onboardingOverlayLocator).toContainText('the menu button') - - // Test we mention what else is in this menu for https://github.com/KittyCAD/modeling-app/issues/2939 - // which doesn't deserver its own full test spun up - const userMenuFeatures = [ - 'manage your account', - 'report a bug', - 'request a feature', - 'sign out', - ] - for (const feature of userMenuFeatures) { - await expect(onboardingOverlayLocator).toContainText(feature) - } - } - ) -}) - -test.fixme( - 'Restarting onboarding on desktop takes one attempt', - async ({ context, page, tronApp }) => { + test('Avatar text updates depending on image load success', async ({ + context, + page, + homePage, + tronApp, + }) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') if (!tronApp) { fail() } await tronApp.cleanProjectDir({ app: { - onboarding_status: 'dismissed', + onboarding_status: '', }, }) - await context.folderSetupFn(async (dir) => { - const routerTemplateDir = join(dir, 'router-template-slate') - await fsp.mkdir(routerTemplateDir, { recursive: true }) - await fsp.copyFile( - executorInputPath('router-template-slate.kcl'), - join(routerTemplateDir, 'main.kcl') - ) - }) + // Override beforeEach test setup + await context.addInitScript( + async ({ settingsKey, settings }) => { + localStorage.setItem(settingsKey, settings) + }, + { + settingsKey: TEST_SETTINGS_KEY, + settings: settingsToToml({ + settings: TEST_SETTINGS_ONBOARDING_USER_MENU, + }), + } + ) - // Our constants - const u = await getUtils(page) - const projectCard = page.getByText('router-template-slate') - const helpMenuButton = page.getByRole('button', { - name: 'Help and resources', - }) - const restartOnboardingButton = page.getByRole('button', { - name: 'Reset onboarding', - }) - const nextButton = page.getByTestId('onboarding-next') + await page.setBodyDimensions({ width: 1200, height: 500 }) + await homePage.goToModelingScene() - const tutorialProjectIndicator = page - .getByTestId('project-sidebar-toggle') - .filter({ hasText: 'Tutorial Project 00' }) - const tutorialModalText = page.getByText('Welcome to Modeling App!') - const tutorialDismissButton = page.getByRole('button', { name: 'Dismiss' }) - const userMenuButton = page.getByTestId('user-sidebar-toggle') - const userMenuSettingsButton = page.getByRole('button', { - name: 'User settings', - }) - const settingsHeading = page.getByRole('heading', { - name: 'Settings', - exact: true, - }) - const restartOnboardingSettingsButton = page.getByRole('button', { - name: 'Replay onboarding', - }) + // Test that the text in this step is correct + const avatarLocator = page.getByTestId('user-sidebar-toggle').locator('img') + const onboardingOverlayLocator = page + .getByTestId('onboarding-content') + .locator('div') + .nth(1) - await test.step('Navigate into project', async () => { - await expect( - page.getByRole('heading', { name: 'Your Projects' }) - ).toBeVisible() - await expect(projectCard).toBeVisible() - await projectCard.click() - await u.waitForPageLoad() - }) + // Expect the avatar to be visible and for the text to reference it + await expect(avatarLocator).toBeVisible() + await expect(onboardingOverlayLocator).toBeVisible() + await expect(onboardingOverlayLocator).toContainText('your avatar') - await test.step('Restart the onboarding from help menu', async () => { - await helpMenuButton.click() - await restartOnboardingButton.click() - - await nextButton.hover() - await nextButton.click() - }) - - await test.step('Confirm that the onboarding has restarted', async () => { - await expect(tutorialProjectIndicator).toBeVisible() - await expect(tutorialModalText).toBeVisible() - // Make sure the model loaded - const XYPlanePoint = { x: 988, y: 523 } as const - const modelColor: [number, number, number] = [76, 76, 76] - - await page.mouse.move(XYPlanePoint.x, XYPlanePoint.y) - await expectPixelColor(page, modelColor, XYPlanePoint, 8) - await tutorialDismissButton.click() - // Make sure model still there. - await expectPixelColor(page, modelColor, XYPlanePoint, 8) - }) - - await test.step('Clear code and restart onboarding from settings', async () => { - await u.openKclCodePanel() - await expect(u.codeLocator).toContainText('// Shelf Bracket') - await u.codeLocator.selectText() - await u.codeLocator.fill('') - - await test.step('Navigate to settings', async () => { - await userMenuButton.click() - await userMenuSettingsButton.click() - await expect(settingsHeading).toBeVisible() - await expect(restartOnboardingSettingsButton).toBeVisible() + // This is to force the avatar to 404. + // For our test image (only triggers locally. on CI, it's Kurt's / + // gravatar image ) + await page.route('/cat.jpg', async (route) => { + await route.fulfill({ + status: 404, + contentType: 'text/plain', + body: 'Not Found!', }) - - await restartOnboardingSettingsButton.click() - // Since the code is empty, we should not see the confirmation dialog - await expect(nextButton).not.toBeVisible() - await expect(tutorialProjectIndicator).toBeVisible() - await expect(tutorialModalText).toBeVisible() }) + + // 404 the CI avatar image + await page.route('https://lh3.googleusercontent.com/**', async (route) => { + await route.fulfill({ + status: 404, + contentType: 'text/plain', + body: 'Not Found!', + }) + }) + + await page.reload({ waitUntil: 'domcontentloaded' }) + + // Now expect the text to be different + await expect(avatarLocator).not.toBeVisible() + await expect(onboardingOverlayLocator).toBeVisible() + await expect(onboardingOverlayLocator).toContainText('the menu button') + }) + + test("Avatar text doesn't mention avatar when no avatar", async ({ + context, + page, + homePage, + tronApp, + }) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') + if (!tronApp) { + fail() + } + + await tronApp.cleanProjectDir({ + app: { + onboarding_status: '', + }, + }) + // Override beforeEach test setup + await context.addInitScript( + async ({ settingsKey, settings }) => { + localStorage.setItem(settingsKey, settings) + localStorage.setItem('FORCE_NO_IMAGE', 'FORCE_NO_IMAGE') + }, + { + settingsKey: TEST_SETTINGS_KEY, + settings: settingsToToml({ + settings: TEST_SETTINGS_ONBOARDING_USER_MENU, + }), + } + ) + + await page.setBodyDimensions({ width: 1200, height: 500 }) + await homePage.goToModelingScene() + + // Test that the text in this step is correct + const sidebar = page.getByTestId('user-sidebar-toggle') + const avatar = sidebar.locator('img') + const onboardingOverlayLocator = page + .getByTestId('onboarding-content') + .locator('div') + .nth(1) + + // Expect the avatar to be visible and for the text to reference it + await expect(avatar).not.toBeVisible() + await expect(onboardingOverlayLocator).toBeVisible() + await expect(onboardingOverlayLocator).toContainText('the menu button') + + // Test we mention what else is in this menu for https://github.com/KittyCAD/modeling-app/issues/2939 + // which doesn't deserver its own full test spun up + const userMenuFeatures = [ + 'manage your account', + 'report a bug', + 'request a feature', + 'sign out', + ] + for (const feature of userMenuFeatures) { + await expect(onboardingOverlayLocator).toContainText(feature) + } + }) +}) + +test('Restarting onboarding on desktop takes one attempt', async ({ + context, + page, + tronApp, +}) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') + if (!tronApp) { + fail() } -) + + await tronApp.cleanProjectDir({ + app: { + onboarding_status: 'dismissed', + }, + }) + + await context.folderSetupFn(async (dir) => { + const routerTemplateDir = join(dir, 'router-template-slate') + await fsp.mkdir(routerTemplateDir, { recursive: true }) + await fsp.copyFile( + executorInputPath('router-template-slate.kcl'), + join(routerTemplateDir, 'main.kcl') + ) + }) + + // Our constants + const u = await getUtils(page) + const projectCard = page.getByText('router-template-slate') + const helpMenuButton = page.getByRole('button', { + name: 'Help and resources', + }) + const restartOnboardingButton = page.getByRole('button', { + name: 'Reset onboarding', + }) + const nextButton = page.getByTestId('onboarding-next') + + const tutorialProjectIndicator = page + .getByTestId('project-sidebar-toggle') + .filter({ hasText: 'Tutorial Project 00' }) + const tutorialModalText = page.getByText('Welcome to Modeling App!') + const tutorialDismissButton = page.getByRole('button', { name: 'Dismiss' }) + const userMenuButton = page.getByTestId('user-sidebar-toggle') + const userMenuSettingsButton = page.getByRole('button', { + name: 'User settings', + }) + const settingsHeading = page.getByRole('heading', { + name: 'Settings', + exact: true, + }) + const restartOnboardingSettingsButton = page.getByRole('button', { + name: 'Replay onboarding', + }) + + await test.step('Navigate into project', async () => { + await expect( + page.getByRole('heading', { name: 'Your Projects' }) + ).toBeVisible() + await expect(projectCard).toBeVisible() + await projectCard.click() + await u.waitForPageLoad() + }) + + await test.step('Restart the onboarding from help menu', async () => { + await helpMenuButton.click() + await restartOnboardingButton.click() + + await nextButton.hover() + await nextButton.click() + }) + + await test.step('Confirm that the onboarding has restarted', async () => { + await expect(tutorialProjectIndicator).toBeVisible() + await expect(tutorialModalText).toBeVisible() + // Make sure the model loaded + const XYPlanePoint = { x: 988, y: 523 } as const + const modelColor: [number, number, number] = [76, 76, 76] + + await page.mouse.move(XYPlanePoint.x, XYPlanePoint.y) + await expectPixelColor(page, modelColor, XYPlanePoint, 8) + await tutorialDismissButton.click() + // Make sure model still there. + await expectPixelColor(page, modelColor, XYPlanePoint, 8) + }) + + await test.step('Clear code and restart onboarding from settings', async () => { + await u.openKclCodePanel() + await expect(u.codeLocator).toContainText('// Shelf Bracket') + await u.codeLocator.selectText() + await u.codeLocator.fill('') + + await test.step('Navigate to settings', async () => { + await userMenuButton.click() + await userMenuSettingsButton.click() + await expect(settingsHeading).toBeVisible() + await expect(restartOnboardingSettingsButton).toBeVisible() + }) + + await restartOnboardingSettingsButton.click() + // Since the code is empty, we should not see the confirmation dialog + await expect(nextButton).not.toBeVisible() + await expect(tutorialProjectIndicator).toBeVisible() + await expect(tutorialModalText).toBeVisible() + }) +}) diff --git a/e2e/playwright/point-click.spec.ts b/e2e/playwright/point-click.spec.ts index 5800a7b7d..6b5f764cb 100644 --- a/e2e/playwright/point-click.spec.ts +++ b/e2e/playwright/point-click.spec.ts @@ -850,157 +850,160 @@ openSketch = startSketchOn('XY') }) }) - test.fixme( - `Shift-click to select and deselect sketch segments`, - async ({ page, homePage, scene, editor }) => { - // Locators - const firstPointLocation = { x: 200, y: 100 } - const secondPointLocation = { x: 800, y: 100 } - const thirdPointLocation = { x: 800, y: 400 } - const fristSegmentLocation = { x: 750, y: 100 } - const secondSegmentLocation = { x: 800, y: 150 } - const planeLocation = { x: 700, y: 200 } + test(`Shift-click to select and deselect sketch segments`, async ({ + page, + homePage, + scene, + editor, + }) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') + // Locators + const firstPointLocation = { x: 200, y: 100 } + const secondPointLocation = { x: 800, y: 100 } + const thirdPointLocation = { x: 800, y: 400 } + const fristSegmentLocation = { x: 750, y: 100 } + const secondSegmentLocation = { x: 800, y: 150 } + const planeLocation = { x: 700, y: 200 } - // Click helpers - const [clickFirstPoint] = scene.makeMouseHelpers( - firstPointLocation.x, - firstPointLocation.y - ) - const [clickSecondPoint] = scene.makeMouseHelpers( - secondPointLocation.x, - secondPointLocation.y - ) - const [clickThirdPoint] = scene.makeMouseHelpers( - thirdPointLocation.x, - thirdPointLocation.y - ) - const [clickFirstSegment] = scene.makeMouseHelpers( - fristSegmentLocation.x, - fristSegmentLocation.y - ) - const [clickSecondSegment] = scene.makeMouseHelpers( - secondSegmentLocation.x, - secondSegmentLocation.y - ) - const [clickPlane] = scene.makeMouseHelpers( - planeLocation.x, - planeLocation.y - ) + // Click helpers + const [clickFirstPoint] = scene.makeMouseHelpers( + firstPointLocation.x, + firstPointLocation.y + ) + const [clickSecondPoint] = scene.makeMouseHelpers( + secondPointLocation.x, + secondPointLocation.y + ) + const [clickThirdPoint] = scene.makeMouseHelpers( + thirdPointLocation.x, + thirdPointLocation.y + ) + const [clickFirstSegment] = scene.makeMouseHelpers( + fristSegmentLocation.x, + fristSegmentLocation.y + ) + const [clickSecondSegment] = scene.makeMouseHelpers( + secondSegmentLocation.x, + secondSegmentLocation.y + ) + const [clickPlane] = scene.makeMouseHelpers( + planeLocation.x, + planeLocation.y + ) - // Colors - const edgeColorWhite: [number, number, number] = [220, 220, 220] - const edgeColorBlue: [number, number, number] = [20, 20, 200] - const backgroundColor: [number, number, number] = [30, 30, 30] - const tolerance = 40 - const timeout = 150 + // Colors + const edgeColorWhite: [number, number, number] = [220, 220, 220] + const edgeColorBlue: [number, number, number] = [20, 20, 200] + const backgroundColor: [number, number, number] = [30, 30, 30] + const tolerance = 40 + const timeout = 150 - // Setup - await test.step(`Initial test setup`, async () => { - await page.setBodyDimensions({ width: 1000, height: 500 }) - await homePage.goToModelingScene() + // Setup + await test.step(`Initial test setup`, async () => { + await page.setBodyDimensions({ width: 1000, height: 500 }) + await homePage.goToModelingScene() - // Wait for the scene and stream to load + // Wait for the scene and stream to load + await scene.expectPixelColor( + backgroundColor, + secondPointLocation, + tolerance + ) + }) + + await test.step('Select and deselect a single sketch segment', async () => { + await test.step('Get into sketch mode', async () => { + await editor.closePane() + await page.waitForTimeout(timeout) + await page.getByRole('button', { name: 'Start Sketch' }).click() + await page.waitForTimeout(timeout) + await clickPlane() + await page.waitForTimeout(1000) + }) + await test.step('Draw sketch', async () => { + await clickFirstPoint() + await page.waitForTimeout(timeout) + await clickSecondPoint() + await page.waitForTimeout(timeout) + await clickThirdPoint() + await page.waitForTimeout(timeout) + }) + await test.step('Deselect line tool', async () => { + const btnLine = page.getByTestId('line') + const btnLineAriaPressed = await btnLine.getAttribute('aria-pressed') + if (btnLineAriaPressed === 'true') { + await btnLine.click() + } + await page.waitForTimeout(timeout) + }) + await test.step('Select the first segment', async () => { + await page.waitForTimeout(timeout) + await clickFirstSegment() + await page.waitForTimeout(timeout) await scene.expectPixelColor( - backgroundColor, - secondPointLocation, + edgeColorBlue, + fristSegmentLocation, + tolerance + ) + await scene.expectPixelColor( + edgeColorWhite, + secondSegmentLocation, tolerance ) }) - - await test.step('Select and deselect a single sketch segment', async () => { - await test.step('Get into sketch mode', async () => { - await editor.closePane() - await page.waitForTimeout(timeout) - await page.getByRole('button', { name: 'Start Sketch' }).click() - await page.waitForTimeout(timeout) - await clickPlane() - await page.waitForTimeout(1000) - }) - await test.step('Draw sketch', async () => { - await clickFirstPoint() - await page.waitForTimeout(timeout) - await clickSecondPoint() - await page.waitForTimeout(timeout) - await clickThirdPoint() - await page.waitForTimeout(timeout) - }) - await test.step('Deselect line tool', async () => { - const btnLine = page.getByTestId('line') - const btnLineAriaPressed = await btnLine.getAttribute('aria-pressed') - if (btnLineAriaPressed === 'true') { - await btnLine.click() - } - await page.waitForTimeout(timeout) - }) - await test.step('Select the first segment', async () => { - await page.waitForTimeout(timeout) - await clickFirstSegment() - await page.waitForTimeout(timeout) - await scene.expectPixelColor( - edgeColorBlue, - fristSegmentLocation, - tolerance - ) - await scene.expectPixelColor( - edgeColorWhite, - secondSegmentLocation, - tolerance - ) - }) - await test.step('Select the second segment (Shift-click)', async () => { - await page.keyboard.down('Shift') - await page.waitForTimeout(timeout) - await clickSecondSegment() - await page.waitForTimeout(timeout) - await page.keyboard.up('Shift') - await scene.expectPixelColor( - edgeColorBlue, - fristSegmentLocation, - tolerance - ) - await scene.expectPixelColor( - edgeColorBlue, - secondSegmentLocation, - tolerance - ) - }) - await test.step('Deselect the first segment', async () => { - await page.keyboard.down('Shift') - await page.waitForTimeout(timeout) - await clickFirstSegment() - await page.waitForTimeout(timeout) - await page.keyboard.up('Shift') - await scene.expectPixelColor( - edgeColorWhite, - fristSegmentLocation, - tolerance - ) - await scene.expectPixelColor( - edgeColorBlue, - secondSegmentLocation, - tolerance - ) - }) - await test.step('Deselect the second segment', async () => { - await page.keyboard.down('Shift') - await page.waitForTimeout(timeout) - await clickSecondSegment() - await page.waitForTimeout(timeout) - await page.keyboard.up('Shift') - await scene.expectPixelColor( - edgeColorWhite, - fristSegmentLocation, - tolerance - ) - await scene.expectPixelColor( - edgeColorWhite, - secondSegmentLocation, - tolerance - ) - }) + await test.step('Select the second segment (Shift-click)', async () => { + await page.keyboard.down('Shift') + await page.waitForTimeout(timeout) + await clickSecondSegment() + await page.waitForTimeout(timeout) + await page.keyboard.up('Shift') + await scene.expectPixelColor( + edgeColorBlue, + fristSegmentLocation, + tolerance + ) + await scene.expectPixelColor( + edgeColorBlue, + secondSegmentLocation, + tolerance + ) }) - } - ) + await test.step('Deselect the first segment', async () => { + await page.keyboard.down('Shift') + await page.waitForTimeout(timeout) + await clickFirstSegment() + await page.waitForTimeout(timeout) + await page.keyboard.up('Shift') + await scene.expectPixelColor( + edgeColorWhite, + fristSegmentLocation, + tolerance + ) + await scene.expectPixelColor( + edgeColorBlue, + secondSegmentLocation, + tolerance + ) + }) + await test.step('Deselect the second segment', async () => { + await page.keyboard.down('Shift') + await page.waitForTimeout(timeout) + await clickSecondSegment() + await page.waitForTimeout(timeout) + await page.keyboard.up('Shift') + await scene.expectPixelColor( + edgeColorWhite, + fristSegmentLocation, + tolerance + ) + await scene.expectPixelColor( + edgeColorWhite, + secondSegmentLocation, + tolerance + ) + }) + }) + }) test(`Offset plane point-and-click`, async ({ context, diff --git a/e2e/playwright/projects.spec.ts b/e2e/playwright/projects.spec.ts index aa8d1a520..0b4262338 100644 --- a/e2e/playwright/projects.spec.ts +++ b/e2e/playwright/projects.spec.ts @@ -1244,10 +1244,11 @@ test( } ) -test.fixme( +test( 'Deleting projects, can delete individual project, can still create projects after deleting all', { tag: '@electron' }, async ({ context, page }, testInfo) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') const projectData = [ ['router-template-slate', 'cylinder.kcl'], ['bracket', 'focusrite_scarlett_mounting_braket.kcl'], @@ -1466,10 +1467,11 @@ test( } ) -test.fixme( +test( 'When the project folder is empty, user can create new project and open it.', { tag: '@electron' }, async ({ page }, testInfo) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') const u = await getUtils(page) await page.setBodyDimensions({ width: 1200, height: 500 }) @@ -2050,10 +2052,11 @@ test( ) // Flaky -test.fixme( +test( 'Original project name persist after onboarding', { tag: '@electron' }, async ({ page }, testInfo) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') await page.setBodyDimensions({ width: 1200, height: 500 }) const getAllProjects = () => page.getByTestId('project-link').all() diff --git a/e2e/playwright/prompt-to-edit.spec.ts b/e2e/playwright/prompt-to-edit.spec.ts index d599df869..bb17c75a4 100644 --- a/e2e/playwright/prompt-to-edit.spec.ts +++ b/e2e/playwright/prompt-to-edit.spec.ts @@ -196,60 +196,65 @@ test.describe('Prompt-to-edit tests', { tag: '@skipWin' }, () => { }) }) - test.fixme( - `manual code selection rename`, - async ({ context, homePage, cmdBar, editor, page, scene }) => { - const body1CapCoords = { x: 571, y: 311 } + test(`manual code selection rename`, async ({ + context, + homePage, + cmdBar, + editor, + page, + scene, + }) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') + const body1CapCoords = { x: 571, y: 311 } - await context.addInitScript((file) => { - localStorage.setItem('persistCode', file) - }, file) - await homePage.goToModelingScene() - await scene.waitForExecutionDone() + await context.addInitScript((file) => { + localStorage.setItem('persistCode', file) + }, file) + await homePage.goToModelingScene() + await scene.waitForExecutionDone() - const submittingToast = page.getByText('Submitting to Text-to-CAD API...') - const successToast = page.getByText('Prompt to edit successful') - const acceptBtn = page.getByRole('button', { name: 'checkmark Accept' }) + const submittingToast = page.getByText('Submitting to Text-to-CAD API...') + const successToast = page.getByText('Prompt to edit successful') + const acceptBtn = page.getByRole('button', { name: 'checkmark Accept' }) - await test.step('wait for scene to load and select code in editor', async () => { - // Find and select the text "sketch002" in the editor - await editor.selectText('sketch002') + await test.step('wait for scene to load and select code in editor', async () => { + // Find and select the text "sketch002" in the editor + await editor.selectText('sketch002') - // Verify the selection was made - await editor.expectState({ - highlightedCode: '', - activeLines: ["sketch002 = startSketchOn('XZ')"], - diagnostics: [], - }) + // Verify the selection was made + await editor.expectState({ + highlightedCode: '', + activeLines: ["sketch002 = startSketchOn('XZ')"], + diagnostics: [], }) + }) - await test.step('fire off edit prompt', async () => { - await scene.expectPixelColor([134, 134, 134], body1CapCoords, 15) - await cmdBar.openCmdBar('promptToEdit') - await page - .getByTestId('cmd-bar-arg-value') - .fill('Please rename to mySketch001') - await page.waitForTimeout(100) - await cmdBar.progressCmdBar() - await expect(submittingToast).toBeVisible() - await expect(submittingToast).not.toBeVisible({ - timeout: 2 * 60_000, - }) - await expect(successToast).toBeVisible() + await test.step('fire off edit prompt', async () => { + await scene.expectPixelColor([134, 134, 134], body1CapCoords, 15) + await cmdBar.openCmdBar('promptToEdit') + await page + .getByTestId('cmd-bar-arg-value') + .fill('Please rename to mySketch001') + await page.waitForTimeout(100) + await cmdBar.progressCmdBar() + await expect(submittingToast).toBeVisible() + await expect(submittingToast).not.toBeVisible({ + timeout: 2 * 60_000, }) + await expect(successToast).toBeVisible() + }) - await test.step('verify rename change and accept it', async () => { - await editor.expectEditor.toContain('mySketch001 = startSketchOn') - await editor.expectEditor.not.toContain('sketch002 = startSketchOn') - await editor.expectEditor.toContain( - 'extrude002 = extrude(mySketch001, length = 50)' - ) + await test.step('verify rename change and accept it', async () => { + await editor.expectEditor.toContain('mySketch001 = startSketchOn') + await editor.expectEditor.not.toContain('sketch002 = startSketchOn') + await editor.expectEditor.toContain( + 'extrude002 = extrude(mySketch001, length = 50)' + ) - await acceptBtn.click() - await expect(successToast).not.toBeVisible() - }) - } - ) + await acceptBtn.click() + await expect(successToast).not.toBeVisible() + }) + }) test('multiple body selections', async ({ context, diff --git a/e2e/playwright/regression-tests.spec.ts b/e2e/playwright/regression-tests.spec.ts index 8732fd2e2..f59f43136 100644 --- a/e2e/playwright/regression-tests.spec.ts +++ b/e2e/playwright/regression-tests.spec.ts @@ -483,10 +483,11 @@ extrude001 = extrude(sketch001, length = 50) } ) - test.fixme( + test( `Network health indicator only appears in modeling view`, { tag: '@electron' }, async ({ context, page }, testInfo) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') await context.folderSetupFn(async (dir) => { const bracketDir = path.join(dir, 'bracket') await fsp.mkdir(bracketDir, { recursive: true }) diff --git a/e2e/playwright/sketch-tests.spec.ts b/e2e/playwright/sketch-tests.spec.ts index e10928db8..907f28c8a 100644 --- a/e2e/playwright/sketch-tests.spec.ts +++ b/e2e/playwright/sketch-tests.spec.ts @@ -188,7 +188,8 @@ sketch001 = startProfileAt([12.34, -12.34], sketch002) page.getByRole('button', { name: 'Start Sketch' }) ).toBeVisible() }) - test.fixme('Can edit segments by dragging their handles', () => { + test('Can edit segments by dragging their handles', () => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') const doEditSegmentsByDraggingHandle = async ( page: Page, homePage: HomePageFixture, @@ -1086,107 +1087,108 @@ profile001 = startProfileAt([${roundOff(scale * 69.6)}, ${roundOff( ) }) // TODO: fix after electron migration is merged - test.fixme( - 'empty-scene default-planes act as expected', - async ({ page, homePage }) => { - /** - * Tests the following things - * 1) The the planes are there on load because the scene is empty - * 2) The planes don't changes color when hovered initially - * 3) Putting something in the scene makes the planes hidden - * 4) Removing everything from the scene shows the plans again - * 3) Once "start sketch" is click, the planes do respond to hovers - * 4) Selecting a plan works as expected, i.e. sketch mode - * 5) Reloading the scene with something already in the scene means the planes are hidden - */ + test('empty-scene default-planes act as expected', async ({ + page, + homePage, + }) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') + /** + * Tests the following things + * 1) The the planes are there on load because the scene is empty + * 2) The planes don't changes color when hovered initially + * 3) Putting something in the scene makes the planes hidden + * 4) Removing everything from the scene shows the plans again + * 3) Once "start sketch" is click, the planes do respond to hovers + * 4) Selecting a plan works as expected, i.e. sketch mode + * 5) Reloading the scene with something already in the scene means the planes are hidden + */ - const u = await getUtils(page) - await homePage.goToModelingScene() + const u = await getUtils(page) + await homePage.goToModelingScene() - await u.openDebugPanel() - await u.expectCmdLog('[data-message-type="execution-done"]') - await u.closeDebugPanel() + await u.openDebugPanel() + await u.expectCmdLog('[data-message-type="execution-done"]') + await u.closeDebugPanel() - const XYPlanePoint = { x: 774, y: 116 } as const - const unHoveredColor: [number, number, number] = [47, 47, 93] - expect( - await u.getGreatestPixDiff(XYPlanePoint, unHoveredColor) - ).toBeLessThan(8) + const XYPlanePoint = { x: 774, y: 116 } as const + const unHoveredColor: [number, number, number] = [47, 47, 93] + expect( + await u.getGreatestPixDiff(XYPlanePoint, unHoveredColor) + ).toBeLessThan(8) - await page.mouse.move(XYPlanePoint.x, XYPlanePoint.y) - await page.waitForTimeout(200) + await page.mouse.move(XYPlanePoint.x, XYPlanePoint.y) + await page.waitForTimeout(200) - // color should not change for having been hovered - expect( - await u.getGreatestPixDiff(XYPlanePoint, unHoveredColor) - ).toBeLessThan(8) + // color should not change for having been hovered + expect( + await u.getGreatestPixDiff(XYPlanePoint, unHoveredColor) + ).toBeLessThan(8) - await u.openAndClearDebugPanel() + await u.openAndClearDebugPanel() - await u.codeLocator.fill(`sketch001 = startSketchOn('XY') + await u.codeLocator.fill(`sketch001 = startSketchOn('XY') |> startProfileAt([-10, -10], %) |> line(end = [20, 0]) |> line(end = [0, 20]) |> xLine(length = -20) `) - await u.expectCmdLog('[data-message-type="execution-done"]') + await u.expectCmdLog('[data-message-type="execution-done"]') - const noPlanesColor: [number, number, number] = [30, 30, 30] - expect( - await u.getGreatestPixDiff(XYPlanePoint, noPlanesColor) - ).toBeLessThan(3) + const noPlanesColor: [number, number, number] = [30, 30, 30] + expect( + await u.getGreatestPixDiff(XYPlanePoint, noPlanesColor) + ).toBeLessThan(3) - await u.clearCommandLogs() - await u.removeCurrentCode() - await u.expectCmdLog('[data-message-type="execution-done"]') + await u.clearCommandLogs() + await u.removeCurrentCode() + await u.expectCmdLog('[data-message-type="execution-done"]') - await expect - .poll(() => u.getGreatestPixDiff(XYPlanePoint, unHoveredColor), { - timeout: 5_000, - }) - .toBeLessThan(8) + await expect + .poll(() => u.getGreatestPixDiff(XYPlanePoint, unHoveredColor), { + timeout: 5_000, + }) + .toBeLessThan(8) - // click start Sketch - await page.getByRole('button', { name: 'Start Sketch' }).click() - await page.mouse.move(XYPlanePoint.x, XYPlanePoint.y, { steps: 50 }) - const hoveredColor: [number, number, number] = [93, 93, 127] - // now that we're expecting the user to select a plan, it does respond to hover - await expect - .poll(() => u.getGreatestPixDiff(XYPlanePoint, hoveredColor)) - .toBeLessThan(8) + // click start Sketch + await page.getByRole('button', { name: 'Start Sketch' }).click() + await page.mouse.move(XYPlanePoint.x, XYPlanePoint.y, { steps: 50 }) + const hoveredColor: [number, number, number] = [93, 93, 127] + // now that we're expecting the user to select a plan, it does respond to hover + await expect + .poll(() => u.getGreatestPixDiff(XYPlanePoint, hoveredColor)) + .toBeLessThan(8) - await page.mouse.click(XYPlanePoint.x, XYPlanePoint.y) - await page.waitForTimeout(600) + await page.mouse.click(XYPlanePoint.x, XYPlanePoint.y) + await page.waitForTimeout(600) - await page.mouse.click(XYPlanePoint.x, XYPlanePoint.y) - await page.waitForTimeout(200) - await page.mouse.click(XYPlanePoint.x + 50, XYPlanePoint.y + 50) - await expect(u.codeLocator).toHaveText(`sketch001 = startSketchOn('XZ') + await page.mouse.click(XYPlanePoint.x, XYPlanePoint.y) + await page.waitForTimeout(200) + await page.mouse.click(XYPlanePoint.x + 50, XYPlanePoint.y + 50) + await expect(u.codeLocator).toHaveText(`sketch001 = startSketchOn('XZ') |> startProfileAt([11.8, 9.09], %) |> line(end = [3.39, -3.39]) `) - await page.addInitScript(async () => { - localStorage.setItem( - 'persistCode', - `sketch001 = startSketchOn('XZ') + await page.addInitScript(async () => { + localStorage.setItem( + 'persistCode', + `sketch001 = startSketchOn('XZ') |> startProfileAt([11.8, 9.09], %) |> line(end = [3.39, -3.39]) ` - ) - }) + ) + }) - await u.openDebugPanel() - await u.expectCmdLog('[data-message-type="execution-done"]') - await u.closeDebugPanel() + await u.openDebugPanel() + await u.expectCmdLog('[data-message-type="execution-done"]') + await u.closeDebugPanel() - // expect there to be no planes on load since there's something in the scene - expect( - await u.getGreatestPixDiff(XYPlanePoint, noPlanesColor) - ).toBeLessThan(3) - } - ) + // expect there to be no planes on load since there's something in the scene + expect( + await u.getGreatestPixDiff(XYPlanePoint, noPlanesColor) + ).toBeLessThan(3) + }) test('Can attempt to sketch on revolved face', async ({ page, homePage }) => { const u = await getUtils(page) @@ -1460,10 +1462,11 @@ test.describe(`Sketching with offset planes`, () => { }) test.describe('multi-profile sketching', () => { - test.fixme( + test( `test it removes half-finished expressions when changing tools in sketch mode`, { tag: ['@skipWin'] }, async ({ context, page, scene, toolbar, editor, homePage, cmdBar }) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') // We seed the scene with a single offset plane await context.addInitScript(() => { localStorage.setItem( @@ -2852,13 +2855,18 @@ loft([profile001, profile002]) ) } ) - test.fixme( - 'Can enter sketch loft edges offsetPlane and continue sketch', - async ({ scene, toolbar, editor, page, homePage }) => { - await page.addInitScript(async () => { - localStorage.setItem( - 'persistCode', - `sketch001 = startSketchOn('XZ') + test('Can enter sketch loft edges offsetPlane and continue sketch', async ({ + scene, + toolbar, + editor, + page, + homePage, + }) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') + await page.addInitScript(async () => { + localStorage.setItem( + 'persistCode', + `sketch001 = startSketchOn('XZ') profile001 = startProfileAt([34, 42.66], sketch001) |> line(end = [102.65, 151.99]) |> line(end = [76, -138.66]) @@ -2874,51 +2882,50 @@ profile002 = startProfileAt([39.43, 172.21], sketch002) loft([profile001, profile002]) ` - ) - }) - - await page.setBodyDimensions({ width: 1000, height: 500 }) - await homePage.goToModelingScene() - await expect( - page.getByRole('button', { name: 'Start Sketch' }) - ).not.toBeDisabled() - - const topProfileEdgeClickCoords = { x: 602, y: 185 } as const - const [topProfileEdgeClick] = scene.makeMouseHelpers( - topProfileEdgeClickCoords.x, - topProfileEdgeClickCoords.y ) - const [sideProfileEdgeClick] = scene.makeMouseHelpers(788, 188) + }) - const [rect1Crn1] = scene.makeMouseHelpers(592, 283) - const [rect1Crn2] = scene.makeMouseHelpers(797, 268) + await page.setBodyDimensions({ width: 1000, height: 500 }) + await homePage.goToModelingScene() + await expect( + page.getByRole('button', { name: 'Start Sketch' }) + ).not.toBeDisabled() - await scene.moveCameraTo( - { x: 8171, y: -7740, z: 1624 }, - { x: 3302, y: -627, z: 2892 } - ) + const topProfileEdgeClickCoords = { x: 602, y: 185 } as const + const [topProfileEdgeClick] = scene.makeMouseHelpers( + topProfileEdgeClickCoords.x, + topProfileEdgeClickCoords.y + ) + const [sideProfileEdgeClick] = scene.makeMouseHelpers(788, 188) - await topProfileEdgeClick() - await page.waitForTimeout(300) - await toolbar.editSketch() - await page.waitForTimeout(600) - await sideProfileEdgeClick() - await page.waitForTimeout(300) - await scene.expectPixelColor(TEST_COLORS.BLUE, { x: 788, y: 188 }, 15) + const [rect1Crn1] = scene.makeMouseHelpers(592, 283) + const [rect1Crn2] = scene.makeMouseHelpers(797, 268) - await toolbar.rectangleBtn.click() - await page.waitForTimeout(100) - await rect1Crn1() - await editor.expectEditor.toContain( - `profile003 = startProfileAt([47.76, -17.13], plane001)` - ) - await rect1Crn2() - await editor.expectEditor.toContain( - `angledLine([0, 106.42], %, $rectangleSegmentA001)` - ) - await page.waitForTimeout(100) - } - ) + await scene.moveCameraTo( + { x: 8171, y: -7740, z: 1624 }, + { x: 3302, y: -627, z: 2892 } + ) + + await topProfileEdgeClick() + await page.waitForTimeout(300) + await toolbar.editSketch() + await page.waitForTimeout(600) + await sideProfileEdgeClick() + await page.waitForTimeout(300) + await scene.expectPixelColor(TEST_COLORS.BLUE, { x: 788, y: 188 }, 15) + + await toolbar.rectangleBtn.click() + await page.waitForTimeout(100) + await rect1Crn1() + await editor.expectEditor.toContain( + `profile003 = startProfileAt([47.76, -17.13], plane001)` + ) + await rect1Crn2() + await editor.expectEditor.toContain( + `angledLine([0, 106.42], %, $rectangleSegmentA001)` + ) + await page.waitForTimeout(100) + }) }) // Regression test for https://github.com/KittyCAD/modeling-app/issues/4891 diff --git a/e2e/playwright/snapshot-tests.spec.ts b/e2e/playwright/snapshot-tests.spec.ts index 9d2dfe6fa..b684cb066 100644 --- a/e2e/playwright/snapshot-tests.spec.ts +++ b/e2e/playwright/snapshot-tests.spec.ts @@ -36,10 +36,11 @@ test.setTimeout(60_000) // a snapshot of it feels weird. I'd rather our regular tests fail. // The primary failure is doExport now relies on the filesystem. We can follow // up with another PR if we want this back. -test.skip( +test( 'exports of each format should work', { tag: ['@snapshot', '@skipWin', '@skipMacos'] }, async ({ page, context, scene, cmdBar, tronApp }) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') if (!tronApp) { fail() } @@ -406,9 +407,6 @@ test( 'Draft segments should look right', { tag: '@snapshot' }, async ({ page, scene, toolbar }) => { - // 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 @@ -585,9 +583,6 @@ test( 'Draft circle should look right', { tag: '@snapshot' }, async ({ page, context, cmdBar, scene }) => { - // 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 @@ -952,9 +947,6 @@ test( ) test.describe('Grid visibility', { tag: '@snapshot' }, () => { - // FIXME: Skip on macos its being weird. - // test.skip(process.platform === 'darwin', 'Skip on macos') - test('Grid turned off to on via command bar', async ({ page, cmdBar, @@ -1097,7 +1089,8 @@ test.describe('Grid visibility', { tag: '@snapshot' }, () => { }) }) -test.fixme('theme persists', async ({ page, context }) => { +test('theme persists', async ({ page, context }) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') const u = await getUtils(page) await context.addInitScript(async () => { localStorage.setItem( diff --git a/e2e/playwright/test-network-and-connection-issues.spec.ts b/e2e/playwright/test-network-and-connection-issues.spec.ts index b1e9b352f..8d03b72a3 100644 --- a/e2e/playwright/test-network-and-connection-issues.spec.ts +++ b/e2e/playwright/test-network-and-connection-issues.spec.ts @@ -3,11 +3,12 @@ import { commonPoints, getUtils } from './test-utils' import { EngineCommand } from 'lang/std/artifactGraph' import { uuidv4 } from 'lib/utils' -test.fixme('Test network and connection issues', () => { +test.describe('Test network and connection issues', () => { test( 'simulate network down and network little widget', { tag: '@skipLocalEngine' }, async ({ page, homePage }) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') const u = await getUtils(page) await page.setBodyDimensions({ width: 1200, height: 500 }) @@ -84,6 +85,7 @@ test.fixme('Test network and connection issues', () => { 'Engine disconnect & reconnect in sketch mode', { tag: '@skipLocalEngine' }, async ({ page, homePage, toolbar }) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') const networkToggle = page.getByTestId('network-toggle') const u = await getUtils(page) diff --git a/e2e/playwright/testing-camera-movement.spec.ts b/e2e/playwright/testing-camera-movement.spec.ts index 8752c3b13..63fef3748 100644 --- a/e2e/playwright/testing-camera-movement.spec.ts +++ b/e2e/playwright/testing-camera-movement.spec.ts @@ -179,169 +179,170 @@ test.describe('Testing Camera Movement', { tag: ['@skipWin'] }, () => { }) // TODO: fix after electron migration is merged - test.fixme( - 'Zoom should be consistent when exiting or entering sketches', - async ({ page, homePage }) => { - // start new sketch pan and zoom before exiting, when exiting the sketch should stay in the same place - // than zoom and pan outside of sketch mode and enter again and it should not change from where it is - // than again for sketching + test('Zoom should be consistent when exiting or entering sketches', async ({ + page, + homePage, + }) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') + // start new sketch pan and zoom before exiting, when exiting the sketch should stay in the same place + // than zoom and pan outside of sketch mode and enter again and it should not change from where it is + // than again for sketching - const u = await getUtils(page) - await page.setBodyDimensions({ width: 1200, height: 500 }) + const u = await getUtils(page) + await page.setBodyDimensions({ width: 1200, height: 500 }) - await homePage.goToModelingScene() - await u.waitForPageLoad() - await u.openDebugPanel() + await homePage.goToModelingScene() + await u.waitForPageLoad() + await u.openDebugPanel() - await expect( - page.getByRole('button', { name: 'Start Sketch' }) - ).not.toBeDisabled() - await expect( - page.getByRole('button', { name: 'Start Sketch' }) - ).toBeVisible() + 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 page.getByRole('button', { name: 'Start Sketch' }).click() + // click on "Start Sketch" button + await u.clearCommandLogs() + await page.getByRole('button', { name: 'Start Sketch' }).click() + await page.waitForTimeout(100) + + // select a plane + await page.mouse.click(700, 325) + + let code = `sketch001 = startSketchOn('XY')` + await expect(u.codeLocator).toHaveText(code) + await u.closeDebugPanel() + + await page.waitForTimeout(500) // TODO detect animation ending, or disable animation + + // move the camera slightly + await page.keyboard.down('Shift') + await page.mouse.move(700, 300) + await page.mouse.down({ button: 'right' }) + await page.mouse.move(800, 200) + await page.mouse.up({ button: 'right' }) + await page.keyboard.up('Shift') + + let y = 350, + x = 948 + + await u.canvasLocator.click({ position: { x: 783, y } }) + code += `\n |> startProfileAt([8.12, -12.98], %)` + // await expect(u.codeLocator).toHaveText(code) + await u.canvasLocator.click({ position: { x, y } }) + code += `\n |> line(end = [11.18, 0])` + // await expect(u.codeLocator).toHaveText(code) + await u.canvasLocator.click({ position: { x, y: 275 } }) + code += `\n |> line(end = [0, 6.99])` + // await expect(u.codeLocator).toHaveText(code) + + // click the line button + await page.getByRole('button', { name: 'line Line', exact: true }).click() + + const hoverOverNothing = async () => { + // await u.canvasLocator.hover({position: {x: 700, y: 325}}) + await page.mouse.move(700, 325) await page.waitForTimeout(100) - - // select a plane - await page.mouse.click(700, 325) - - let code = `sketch001 = startSketchOn('XY')` - await expect(u.codeLocator).toHaveText(code) - await u.closeDebugPanel() - - await page.waitForTimeout(500) // TODO detect animation ending, or disable animation - - // move the camera slightly - await page.keyboard.down('Shift') - await page.mouse.move(700, 300) - await page.mouse.down({ button: 'right' }) - await page.mouse.move(800, 200) - await page.mouse.up({ button: 'right' }) - await page.keyboard.up('Shift') - - let y = 350, - x = 948 - - await u.canvasLocator.click({ position: { x: 783, y } }) - code += `\n |> startProfileAt([8.12, -12.98], %)` - // await expect(u.codeLocator).toHaveText(code) - await u.canvasLocator.click({ position: { x, y } }) - code += `\n |> line(end = [11.18, 0])` - // await expect(u.codeLocator).toHaveText(code) - await u.canvasLocator.click({ position: { x, y: 275 } }) - code += `\n |> line(end = [0, 6.99])` - // await expect(u.codeLocator).toHaveText(code) - - // click the line button - await page.getByRole('button', { name: 'line Line', exact: true }).click() - - const hoverOverNothing = async () => { - // await u.canvasLocator.hover({position: {x: 700, y: 325}}) - await page.mouse.move(700, 325) - await page.waitForTimeout(100) - await expect(page.getByTestId('hover-highlight')).not.toBeVisible({ - timeout: 10_000, - }) - } - - await expect(page.getByTestId('hover-highlight')).not.toBeVisible() - - await page.waitForTimeout(200) - // hover over horizontal line - await u.canvasLocator.hover({ position: { x: 800, y } }) - await expect(page.getByTestId('hover-highlight').first()).toBeVisible({ - timeout: 10_000, - }) - await page.waitForTimeout(200) - - await hoverOverNothing() - await page.waitForTimeout(200) - // hover over vertical line - await u.canvasLocator.hover({ position: { x, y: 325 } }) - await expect(page.getByTestId('hover-highlight').first()).toBeVisible({ - timeout: 10_000, - }) - - await hoverOverNothing() - - // click exit sketch - await page.getByRole('button', { name: 'Exit Sketch' }).click() - await page.waitForTimeout(400) - - await hoverOverNothing() - await page.waitForTimeout(200) - // hover over horizontal line - await page.mouse.move(858, y, { steps: 5 }) - await expect(page.getByTestId('hover-highlight').first()).toBeVisible({ - timeout: 10_000, - }) - - await hoverOverNothing() - - // hover over vertical line - await page.mouse.move(x, 325) - await expect(page.getByTestId('hover-highlight').first()).toBeVisible({ - timeout: 10_000, - }) - - await hoverOverNothing() - - // hover over vertical line - await page.mouse.move(857, y) - await expect(page.getByTestId('hover-highlight').first()).toBeVisible({ - timeout: 10_000, - }) - // now click it - await page.mouse.click(857, y) - - await expect( - page.getByRole('button', { name: 'Edit Sketch' }) - ).toBeVisible() - await hoverOverNothing() - await page.getByRole('button', { name: 'Edit Sketch' }).click() - - await page.waitForTimeout(400) - - x = 975 - y = 468 - - await page.waitForTimeout(100) - await page.mouse.move(x, 419, { steps: 5 }) - await expect(page.getByTestId('hover-highlight').first()).toBeVisible({ - timeout: 10_000, - }) - - await hoverOverNothing() - - await page.mouse.move(855, y) - await expect(page.getByTestId('hover-highlight').first()).toBeVisible({ - timeout: 10_000, - }) - - await hoverOverNothing() - - await page.getByRole('button', { name: 'Exit Sketch' }).click() - await page.waitForTimeout(200) - - await hoverOverNothing() - await page.waitForTimeout(200) - - await page.mouse.move(x, 419) - await expect(page.getByTestId('hover-highlight').first()).toBeVisible({ - timeout: 10_000, - }) - - await hoverOverNothing() - - await page.mouse.move(855, y) - await expect(page.getByTestId('hover-highlight').first()).toBeVisible({ + await expect(page.getByTestId('hover-highlight')).not.toBeVisible({ timeout: 10_000, }) } - ) + + await expect(page.getByTestId('hover-highlight')).not.toBeVisible() + + await page.waitForTimeout(200) + // hover over horizontal line + await u.canvasLocator.hover({ position: { x: 800, y } }) + await expect(page.getByTestId('hover-highlight').first()).toBeVisible({ + timeout: 10_000, + }) + await page.waitForTimeout(200) + + await hoverOverNothing() + await page.waitForTimeout(200) + // hover over vertical line + await u.canvasLocator.hover({ position: { x, y: 325 } }) + await expect(page.getByTestId('hover-highlight').first()).toBeVisible({ + timeout: 10_000, + }) + + await hoverOverNothing() + + // click exit sketch + await page.getByRole('button', { name: 'Exit Sketch' }).click() + await page.waitForTimeout(400) + + await hoverOverNothing() + await page.waitForTimeout(200) + // hover over horizontal line + await page.mouse.move(858, y, { steps: 5 }) + await expect(page.getByTestId('hover-highlight').first()).toBeVisible({ + timeout: 10_000, + }) + + await hoverOverNothing() + + // hover over vertical line + await page.mouse.move(x, 325) + await expect(page.getByTestId('hover-highlight').first()).toBeVisible({ + timeout: 10_000, + }) + + await hoverOverNothing() + + // hover over vertical line + await page.mouse.move(857, y) + await expect(page.getByTestId('hover-highlight').first()).toBeVisible({ + timeout: 10_000, + }) + // now click it + await page.mouse.click(857, y) + + await expect( + page.getByRole('button', { name: 'Edit Sketch' }) + ).toBeVisible() + await hoverOverNothing() + await page.getByRole('button', { name: 'Edit Sketch' }).click() + + await page.waitForTimeout(400) + + x = 975 + y = 468 + + await page.waitForTimeout(100) + await page.mouse.move(x, 419, { steps: 5 }) + await expect(page.getByTestId('hover-highlight').first()).toBeVisible({ + timeout: 10_000, + }) + + await hoverOverNothing() + + await page.mouse.move(855, y) + await expect(page.getByTestId('hover-highlight').first()).toBeVisible({ + timeout: 10_000, + }) + + await hoverOverNothing() + + await page.getByRole('button', { name: 'Exit Sketch' }).click() + await page.waitForTimeout(200) + + await hoverOverNothing() + await page.waitForTimeout(200) + + await page.mouse.move(x, 419) + await expect(page.getByTestId('hover-highlight').first()).toBeVisible({ + timeout: 10_000, + }) + + await hoverOverNothing() + + await page.mouse.move(855, y) + await expect(page.getByTestId('hover-highlight').first()).toBeVisible({ + timeout: 10_000, + }) + }) test(`Zoom by scroll should not fire while orbiting`, async ({ homePage, diff --git a/e2e/playwright/testing-constraints.spec.ts b/e2e/playwright/testing-constraints.spec.ts index 7864c3746..aefed0288 100644 --- a/e2e/playwright/testing-constraints.spec.ts +++ b/e2e/playwright/testing-constraints.spec.ts @@ -1005,114 +1005,108 @@ part002 = startSketchOn('XZ') } }) - test.fixme( - 'Horizontally constrained line remains selected after applying constraint', - async ({ page, homePage }) => { - test.setTimeout(70_000) - await page.addInitScript(async () => { - localStorage.setItem( - 'persistCode', - `sketch001 = startSketchOn('XY') + test('Horizontally constrained line remains selected after applying constraint', async ({ + page, + homePage, + }) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') + test.setTimeout(70_000) + await page.addInitScript(async () => { + localStorage.setItem( + 'persistCode', + `sketch001 = startSketchOn('XY') |> startProfileAt([-1.05, -1.07], %) |> line(end = [3.79, 2.68], tag = $seg01) |> line(end = [3.13, -2.4])` - ) + ) + }) + const u = await getUtils(page) + await page.setBodyDimensions({ width: 1200, height: 500 }) + + await homePage.goToModelingScene() + await u.waitForPageLoad() + + await page.getByText('line(end = [3.79, 2.68], tag = $seg01)').click() + await expect(page.getByRole('button', { name: 'Edit Sketch' })).toBeEnabled( + { timeout: 10_000 } + ) + await page.getByRole('button', { name: 'Edit Sketch' }).click() + + // Wait for overlays to populate + await page.waitForTimeout(1000) + + await page.waitForTimeout(100) + const lineBefore = await u.getSegmentBodyCoords( + `[data-overlay-index="1"]`, + 0 + ) + expect( + await u.getGreatestPixDiff(lineBefore, TEST_COLORS.WHITE) + ).toBeLessThan(3) + await page.mouse.move(lineBefore.x, lineBefore.y) + await page.waitForTimeout(50) + await page.mouse.click(lineBefore.x, lineBefore.y) + expect( + await u.getGreatestPixDiff(lineBefore, TEST_COLORS.BLUE) + ).toBeLessThan(3) + + await page + .getByRole('button', { + name: 'Length: open menu', }) - const u = await getUtils(page) - await page.setBodyDimensions({ width: 1200, height: 500 }) + .click() + await page.waitForTimeout(500) + await page.getByRole('button', { name: 'Horizontal', exact: true }).click() + await page.waitForTimeout(500) - await homePage.goToModelingScene() - await u.waitForPageLoad() + await pollEditorLinesSelectedLength(page, 1) + let activeLinesContent = await page.locator('.cm-activeLine').all() + await expect(activeLinesContent[0]).toHaveText(`|> xLine(length = 3.13)`) - await page.getByText('line(end = [3.79, 2.68], tag = $seg01)').click() - await expect( - page.getByRole('button', { name: 'Edit Sketch' }) - ).toBeEnabled({ timeout: 10_000 }) - await page.getByRole('button', { name: 'Edit Sketch' }).click() + // Wait for code editor to settle. + await page.waitForTimeout(2000) - // Wait for overlays to populate - await page.waitForTimeout(1000) + // If the overlay-angle is updated the THREE.js scene is in a good state + await expect( + await page.locator('[data-overlay-index="1"]') + ).toHaveAttribute('data-overlay-angle', '0') - await page.waitForTimeout(100) - const lineBefore = await u.getSegmentBodyCoords( - `[data-overlay-index="1"]`, - 0 - ) - expect( - await u.getGreatestPixDiff(lineBefore, TEST_COLORS.WHITE) - ).toBeLessThan(3) - await page.mouse.move(lineBefore.x, lineBefore.y) - await page.waitForTimeout(50) - await page.mouse.click(lineBefore.x, lineBefore.y) - expect( - await u.getGreatestPixDiff(lineBefore, TEST_COLORS.BLUE) - ).toBeLessThan(3) + const lineAfter = await u.getSegmentBodyCoords( + `[data-overlay-index="1"]`, + 0 + ) - await page - .getByRole('button', { - name: 'Length: open menu', - }) - .click() - await page.waitForTimeout(500) - await page - .getByRole('button', { name: 'Horizontal', exact: true }) - .click() - await page.waitForTimeout(500) + const linebb = await u.getBoundingBox('[data-overlay-index="1"]') + await page.mouse.move(linebb.x, linebb.y, { steps: 25 }) + await page.mouse.click(linebb.x, linebb.y) - await pollEditorLinesSelectedLength(page, 1) - let activeLinesContent = await page.locator('.cm-activeLine').all() - await expect(activeLinesContent[0]).toHaveText(`|> xLine(length = 3.13)`) + await expect + .poll(async () => await u.getGreatestPixDiff(lineAfter, TEST_COLORS.BLUE)) + .toBeLessThan(3) - // Wait for code editor to settle. - await page.waitForTimeout(2000) + await page.waitForTimeout(500) - // If the overlay-angle is updated the THREE.js scene is in a good state - await expect( - await page.locator('[data-overlay-index="1"]') - ).toHaveAttribute('data-overlay-angle', '0') + // await expect(page.getByRole('button', { name: 'length', exact: true })).toBeVisible() + await page.waitForTimeout(200) + // await page.getByRole('button', { name: 'length', exact: true }).click() + await page.getByTestId('constraint-length').click() - const lineAfter = await u.getSegmentBodyCoords( - `[data-overlay-index="1"]`, - 0 - ) + await page.getByTestId('cmd-bar-arg-value').getByRole('textbox').fill('10') + await page + .getByRole('button', { + name: 'arrow right Continue', + }) + .click() - const linebb = await u.getBoundingBox('[data-overlay-index="1"]') - await page.mouse.move(linebb.x, linebb.y, { steps: 25 }) - await page.mouse.click(linebb.x, linebb.y) + await pollEditorLinesSelectedLength(page, 1) + activeLinesContent = await page.locator('.cm-activeLine').all() + await expect(activeLinesContent[0]).toHaveText( + `|> xLine(length = length001)` + ) - await expect - .poll( - async () => await u.getGreatestPixDiff(lineAfter, TEST_COLORS.BLUE) - ) - .toBeLessThan(3) - - await page.waitForTimeout(500) - - // await expect(page.getByRole('button', { name: 'length', exact: true })).toBeVisible() - await page.waitForTimeout(200) - // await page.getByRole('button', { name: 'length', exact: true }).click() - await page.getByTestId('constraint-length').click() - - await page - .getByTestId('cmd-bar-arg-value') - .getByRole('textbox') - .fill('10') - await page - .getByRole('button', { - name: 'arrow right Continue', - }) - .click() - - await pollEditorLinesSelectedLength(page, 1) - activeLinesContent = await page.locator('.cm-activeLine').all() - await expect(activeLinesContent[0]).toHaveText( - `|> xLine(length = length001)` - ) - - // checking the count of the overlays is a good proxy check that the client sketch scene is in a good state - await expect(page.getByTestId('segment-overlay')).toHaveCount(2) - } - ) + // checking the count of the overlays is a good proxy check that the client sketch scene is in a good state + await expect(page.getByTestId('segment-overlay')).toHaveCount(2) + }) }) test.describe('Electron constraint tests', () => { test( diff --git a/e2e/playwright/testing-perspective-toggle.spec.ts b/e2e/playwright/testing-perspective-toggle.spec.ts index ed589fe78..48363973c 100644 --- a/e2e/playwright/testing-perspective-toggle.spec.ts +++ b/e2e/playwright/testing-perspective-toggle.spec.ts @@ -2,7 +2,8 @@ import { test, expect } from './zoo-test' import { getUtils } from './test-utils' test.describe('Test toggling perspective', () => { - test.fixme('via command palette and toggle', async ({ page, homePage }) => { + test('via command palette and toggle', async ({ page, homePage }) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') const u = await getUtils(page) // Locators and constants diff --git a/e2e/playwright/testing-segment-overlays.spec.ts b/e2e/playwright/testing-segment-overlays.spec.ts index e3d9bbaa7..ddd0c265c 100644 --- a/e2e/playwright/testing-segment-overlays.spec.ts +++ b/e2e/playwright/testing-segment-overlays.spec.ts @@ -7,207 +7,205 @@ import { uuidv4 } from 'lib/utils' import { EditorFixture } from './fixtures/editorFixture' test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { - test.fixme( - 'Hover over a segment should show its overlay, hovering over the input overlays should show its popover, clicking the input overlay should constrain/unconstrain it:\nfor the following segments', - () => { - // TODO: fix this test on mac after the electron migration - test.skip(process.platform === 'darwin', 'Skip on mac') - /** - * Clicks on an constrained element - * @param {Page} page - The page to perform the action on - * @param {Object} options - The options for the action - * @param {Object} options.hoverPos - The position to hover over - * @param {Object} options.constraintType - The type of constraint - * @param {number} options.ang - The angle - * @param {number} options.steps - The number of steps to perform - */ - const _clickConstrained = - (page: Page, editor: EditorFixture) => - async ({ - hoverPos, - constraintType, - expectBeforeUnconstrained, - expectAfterUnconstrained, - expectFinal, - ang = 45, - steps = 10, - locator, - }: { - hoverPos: { x: number; y: number } - constraintType: - | 'horizontal' - | 'vertical' - | 'tangentialWithPrevious' - | LineInputsType - expectBeforeUnconstrained: string - expectAfterUnconstrained: string - expectFinal: string - ang?: number - steps?: number - locator?: string - }) => { - await expect(page.getByText('Added variable')).not.toBeVisible() - - await page.mouse.move(0, 0) - await page.waitForTimeout(1000) - 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, locator) - await page.mouse.move(x, y) - - await editor.expectEditor.toContain(expectBeforeUnconstrained, { - shouldNormalise: true, - }) - 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) - await constrainedLocator.click() - await editor.expectEditor.toContain(expectAfterUnconstrained, { - shouldNormalise: true, - }) - - await page.mouse.move(0, 0) - await page.waitForTimeout(1000) - 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, locator) - await page.mouse.move(x, y) - - 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) - await unconstrainedLocator.click() - await expect( - page.getByTestId('cmd-bar-arg-value').getByRole('textbox') - ).toBeFocused() - await page - .getByRole('button', { - name: 'arrow right Continue', - }) - .click() - await expect(page.locator('.cm-content')).toContainText(expectFinal) - await editor.expectEditor.toContain(expectFinal, { - shouldNormalise: true, - }) - await editor.expectEditor.toContain(expectFinal, { - shouldNormalise: true, - }) - } - - /** - * Clicks on an unconstrained element - * @param {Page} page - The page to perform the action on - * @param {Object} options - The options for the action - * @param {Object} options.hoverPos - The position to hover over - * @param {Object} options.constraintType - The type of constraint - * @param {number} options.ang - The angle - * @param {number} options.steps - The number of steps to perform - */ - const _clickUnconstrained = - (page: Page, editor: EditorFixture) => - async ({ - hoverPos, - constraintType, - expectBeforeUnconstrained, - expectAfterUnconstrained, - expectFinal, - ang = 45, - steps = 5, - locator, - }: { - hoverPos: { x: number; y: number } - constraintType: - | 'horizontal' - | 'vertical' - | 'tangentialWithPrevious' - | LineInputsType - expectBeforeUnconstrained: string - expectAfterUnconstrained: string - expectFinal: string - ang?: number - steps?: number - locator?: string - }) => { - await page.mouse.move(0, 0) - await page.waitForTimeout(1000) - 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, locator) - await page.mouse.move(x, y) - - await expect(page.getByText('Added variable')).not.toBeVisible() - await editor.expectEditor.toContain(expectBeforeUnconstrained, { - shouldNormalise: true, - }) - const unconstrainedLocator = page.locator( - `[data-constraint-type="${constraintType}"][data-is-constrained="false"]` - ) - await unconstrainedLocator.hover() - await expect( - await page.getByTestId('constraint-symbol-popover').count() - ).toBeGreaterThan(0) - await unconstrainedLocator.click() - await expect( - page.getByTestId('cmd-bar-arg-value').getByRole('textbox') - ).toBeFocused() - await page - .getByRole('button', { - name: 'arrow right Continue', - }) - .click() - await editor.expectEditor.toContain(expectAfterUnconstrained, { - shouldNormalise: true, - }) - await expect(page.getByText('Added variable')).not.toBeVisible() - - await page.mouse.move(0, 0) - await page.waitForTimeout(1000) - 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, locator) - await page.mouse.move(x, y) - - 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) - await constrainedLocator.click() - await editor.expectEditor.toContain(expectFinal, { - shouldNormalise: true, - }) - } - test.setTimeout(120000) - test('for segments [line, angledLine, xLineTo]', async ({ - page, - editor, - homePage, + test('Hover over a segment should show its overlay, hovering over the input overlays should show its popover, clicking the input overlay should constrain/unconstrain it:\nfor the following segments', () => { + // TODO: fix this test on mac after the electron migration + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') + /** + * Clicks on an constrained element + * @param {Page} page - The page to perform the action on + * @param {Object} options - The options for the action + * @param {Object} options.hoverPos - The position to hover over + * @param {Object} options.constraintType - The type of constraint + * @param {number} options.ang - The angle + * @param {number} options.steps - The number of steps to perform + */ + const _clickConstrained = + (page: Page, editor: EditorFixture) => + async ({ + hoverPos, + constraintType, + expectBeforeUnconstrained, + expectAfterUnconstrained, + expectFinal, + ang = 45, + steps = 10, + locator, + }: { + hoverPos: { x: number; y: number } + constraintType: + | 'horizontal' + | 'vertical' + | 'tangentialWithPrevious' + | LineInputsType + expectBeforeUnconstrained: string + expectAfterUnconstrained: string + expectFinal: string + ang?: number + steps?: number + locator?: string }) => { - await page.addInitScript(async () => { - localStorage.setItem( - 'persistCode', - `part001 = startSketchOn('XZ') + await expect(page.getByText('Added variable')).not.toBeVisible() + + await page.mouse.move(0, 0) + await page.waitForTimeout(1000) + 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, locator) + await page.mouse.move(x, y) + + await editor.expectEditor.toContain(expectBeforeUnconstrained, { + shouldNormalise: true, + }) + 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) + await constrainedLocator.click() + await editor.expectEditor.toContain(expectAfterUnconstrained, { + shouldNormalise: true, + }) + + await page.mouse.move(0, 0) + await page.waitForTimeout(1000) + 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, locator) + await page.mouse.move(x, y) + + 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) + await unconstrainedLocator.click() + await expect( + page.getByTestId('cmd-bar-arg-value').getByRole('textbox') + ).toBeFocused() + await page + .getByRole('button', { + name: 'arrow right Continue', + }) + .click() + await expect(page.locator('.cm-content')).toContainText(expectFinal) + await editor.expectEditor.toContain(expectFinal, { + shouldNormalise: true, + }) + await editor.expectEditor.toContain(expectFinal, { + shouldNormalise: true, + }) + } + + /** + * Clicks on an unconstrained element + * @param {Page} page - The page to perform the action on + * @param {Object} options - The options for the action + * @param {Object} options.hoverPos - The position to hover over + * @param {Object} options.constraintType - The type of constraint + * @param {number} options.ang - The angle + * @param {number} options.steps - The number of steps to perform + */ + const _clickUnconstrained = + (page: Page, editor: EditorFixture) => + async ({ + hoverPos, + constraintType, + expectBeforeUnconstrained, + expectAfterUnconstrained, + expectFinal, + ang = 45, + steps = 5, + locator, + }: { + hoverPos: { x: number; y: number } + constraintType: + | 'horizontal' + | 'vertical' + | 'tangentialWithPrevious' + | LineInputsType + expectBeforeUnconstrained: string + expectAfterUnconstrained: string + expectFinal: string + ang?: number + steps?: number + locator?: string + }) => { + await page.mouse.move(0, 0) + await page.waitForTimeout(1000) + 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, locator) + await page.mouse.move(x, y) + + await expect(page.getByText('Added variable')).not.toBeVisible() + await editor.expectEditor.toContain(expectBeforeUnconstrained, { + shouldNormalise: true, + }) + const unconstrainedLocator = page.locator( + `[data-constraint-type="${constraintType}"][data-is-constrained="false"]` + ) + await unconstrainedLocator.hover() + await expect( + await page.getByTestId('constraint-symbol-popover').count() + ).toBeGreaterThan(0) + await unconstrainedLocator.click() + await expect( + page.getByTestId('cmd-bar-arg-value').getByRole('textbox') + ).toBeFocused() + await page + .getByRole('button', { + name: 'arrow right Continue', + }) + .click() + await editor.expectEditor.toContain(expectAfterUnconstrained, { + shouldNormalise: true, + }) + await expect(page.getByText('Added variable')).not.toBeVisible() + + await page.mouse.move(0, 0) + await page.waitForTimeout(1000) + 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, locator) + await page.mouse.move(x, y) + + 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) + await constrainedLocator.click() + await editor.expectEditor.toContain(expectFinal, { + shouldNormalise: true, + }) + } + test.setTimeout(120000) + test('for segments [line, angledLine, xLineTo]', async ({ + page, + editor, + homePage, + }) => { + await page.addInitScript(async () => { + localStorage.setItem( + 'persistCode', + `part001 = startSketchOn('XZ') |> startProfileAt([5 + 0, 20 + 0], %) |> line(end = [0.5, -14 + 0]) |> angledLine({ angle = 3 + 0, length = 32 + 0 }, %) @@ -227,154 +225,157 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { }, %) |> tangentialArcTo([5 + 3.14 + 13, 20 + 3.14], %) ` - ) - }) - const u = await getUtils(page) - await page.setBodyDimensions({ width: 1200, height: 500 }) + ) + }) + const u = await getUtils(page) + await page.setBodyDimensions({ width: 1200, height: 500 }) - await homePage.goToModelingScene() + await homePage.goToModelingScene() - // wait for execution done - await u.openDebugPanel() - await u.expectCmdLog('[data-message-type="execution-done"]') - await u.closeDebugPanel() + // wait for execution done + await u.openDebugPanel() + await u.expectCmdLog('[data-message-type="execution-done"]') + await u.closeDebugPanel() - await page.getByText('xLine(endAbsolute = 5 + 9 - 5)').click() - await page.waitForTimeout(100) - await page.getByRole('button', { name: 'Edit Sketch' }).click() - await page.waitForTimeout(500) + await page.getByText('xLine(endAbsolute = 5 + 9 - 5)').click() + await page.waitForTimeout(100) + await page.getByRole('button', { name: 'Edit Sketch' }).click() + await page.waitForTimeout(500) - await expect(page.getByTestId('segment-overlay')).toHaveCount(13) + await expect(page.getByTestId('segment-overlay')).toHaveCount(13) - const clickUnconstrained = _clickUnconstrained(page, editor) - const clickConstrained = _clickConstrained(page, editor) + const clickUnconstrained = _clickUnconstrained(page, editor) + const clickConstrained = _clickConstrained(page, editor) - await u.openAndClearDebugPanel() - await u.sendCustomCmd({ - type: 'modeling_cmd_req', - cmd_id: uuidv4(), - cmd: { - type: 'default_camera_look_at', - vantage: { x: 80, y: -1350, z: 510 }, - center: { x: 80, y: 0, z: 510 }, - 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) - await u.closeDebugPanel() + await u.openAndClearDebugPanel() + await u.sendCustomCmd({ + type: 'modeling_cmd_req', + cmd_id: uuidv4(), + cmd: { + type: 'default_camera_look_at', + vantage: { x: 80, y: -1350, z: 510 }, + center: { x: 80, y: 0, z: 510 }, + 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) + await u.closeDebugPanel() - let ang = 0 + let ang = 0 - const line = await u.getBoundingBox('[data-overlay-index="0"]') - ang = await u.getAngle('[data-overlay-index="0"]') - console.log('line1', line, ang) - await clickConstrained({ - hoverPos: { x: line.x, y: line.y }, - constraintType: 'yRelative', - expectBeforeUnconstrained: '|> line(end = [0.5, -14 + 0])', - expectAfterUnconstrained: '|> line(end = [0.5, -14])', - expectFinal: '|> line(end = [0.5, yRel001])', - ang: ang + 180, - locator: '[data-overlay-toolbar-index="0"]', - }) - console.log('line2') - await clickUnconstrained({ - hoverPos: { x: line.x, y: line.y }, - constraintType: 'xRelative', - expectBeforeUnconstrained: '|> line(end = [0.5, yRel001])', - expectAfterUnconstrained: 'line(end = [xRel001, yRel001])', - expectFinal: '|> line(end = [0.5, yRel001])', - ang: ang + 180, - locator: '[data-overlay-index="0"]', - }) - - const angledLine = await u.getBoundingBox('[data-overlay-index="1"]') - ang = await u.getAngle('[data-overlay-index="1"]') - console.log('angledLine1') - await clickConstrained({ - hoverPos: { x: angledLine.x, y: angledLine.y }, - constraintType: 'angle', - expectBeforeUnconstrained: - 'angledLine({ angle = 3 + 0, length = 32 + 0 }, %)', - expectAfterUnconstrained: - 'angledLine({ angle = 3, length = 32 + 0 }, %)', - expectFinal: 'angledLine({ angle = angle001, length = 32 + 0 }, %)', - ang: ang + 180, - locator: '[data-overlay-toolbar-index="1"]', - }) - console.log('angledLine2') - await clickConstrained({ - hoverPos: { x: angledLine.x, y: angledLine.y }, - constraintType: 'length', - expectBeforeUnconstrained: - 'angledLine({ angle = angle001, length = 32 + 0 }, %)', - expectAfterUnconstrained: - 'angledLine({ angle = angle001, length = 32 }, %)', - expectFinal: 'angledLine({ angle = angle001, length = len001 }, %)', - ang: ang + 180, - locator: '[data-overlay-toolbar-index="1"]', - }) - - await page.mouse.move(700, 250) - await page.waitForTimeout(100) - - let lineTo = await u.getBoundingBox('[data-overlay-index="2"]') - ang = await u.getAngle('[data-overlay-index="2"]') - console.log('lineTo1') - await clickConstrained({ - hoverPos: { x: lineTo.x, y: lineTo.y }, - constraintType: 'yAbsolute', - expectBeforeUnconstrained: - 'line(endAbsolute = [5 + 33, 20 + 11.5 + 0])', - expectAfterUnconstrained: 'line(endAbsolute = [5 + 33, 31.5])', - expectFinal: 'line(endAbsolute = [5 + 33, yAbs001])', - steps: 8, - ang: ang + 180, - locator: '[data-overlay-toolbar-index="2"]', - }) - console.log('lineTo2') - await clickConstrained({ - hoverPos: { x: lineTo.x, y: lineTo.y }, - constraintType: 'xAbsolute', - expectBeforeUnconstrained: 'line(endAbsolute = [5 + 33, yAbs001])', - expectAfterUnconstrained: 'line(endAbsolute = [38, yAbs001])', - expectFinal: 'line(endAbsolute = [xAbs001, yAbs001])', - steps: 8, - ang: ang + 180, - locator: '[data-overlay-toolbar-index="2"]', - }) - - const xLineTo = await u.getBoundingBox('[data-overlay-index="3"]') - ang = await u.getAngle('[data-overlay-index="3"]') - console.log('xlineTo1') - await clickConstrained({ - hoverPos: { x: xLineTo.x, y: xLineTo.y }, - constraintType: 'xAbsolute', - expectBeforeUnconstrained: 'xLine(endAbsolute = 5 + 9 - 5)', - expectAfterUnconstrained: 'xLine(endAbsolute = 9)', - expectFinal: 'xLine(endAbsolute = xAbs002)', - ang: ang + 180, - steps: 8, - locator: '[data-overlay-toolbar-index="3"]', - }) + const line = await u.getBoundingBox('[data-overlay-index="0"]') + ang = await u.getAngle('[data-overlay-index="0"]') + console.log('line1', line, ang) + await clickConstrained({ + hoverPos: { x: line.x, y: line.y }, + constraintType: 'yRelative', + expectBeforeUnconstrained: '|> line(end = [0.5, -14 + 0])', + expectAfterUnconstrained: '|> line(end = [0.5, -14])', + expectFinal: '|> line(end = [0.5, yRel001])', + ang: ang + 180, + locator: '[data-overlay-toolbar-index="0"]', + }) + console.log('line2') + await clickUnconstrained({ + hoverPos: { x: line.x, y: line.y }, + constraintType: 'xRelative', + expectBeforeUnconstrained: '|> line(end = [0.5, yRel001])', + expectAfterUnconstrained: 'line(end = [xRel001, yRel001])', + expectFinal: '|> line(end = [0.5, yRel001])', + ang: ang + 180, + locator: '[data-overlay-index="0"]', }) - // Broken on main at time of writing! - test.fixme( - 'for segments [yLineTo, xLine]', - async ({ page, editor, homePage }) => { - await page.addInitScript(async () => { - localStorage.setItem( - 'persistCode', - `yRel001 = -14 + const angledLine = await u.getBoundingBox('[data-overlay-index="1"]') + ang = await u.getAngle('[data-overlay-index="1"]') + console.log('angledLine1') + await clickConstrained({ + hoverPos: { x: angledLine.x, y: angledLine.y }, + constraintType: 'angle', + expectBeforeUnconstrained: + 'angledLine({ angle = 3 + 0, length = 32 + 0 }, %)', + expectAfterUnconstrained: + 'angledLine({ angle = 3, length = 32 + 0 }, %)', + expectFinal: 'angledLine({ angle = angle001, length = 32 + 0 }, %)', + ang: ang + 180, + locator: '[data-overlay-toolbar-index="1"]', + }) + console.log('angledLine2') + await clickConstrained({ + hoverPos: { x: angledLine.x, y: angledLine.y }, + constraintType: 'length', + expectBeforeUnconstrained: + 'angledLine({ angle = angle001, length = 32 + 0 }, %)', + expectAfterUnconstrained: + 'angledLine({ angle = angle001, length = 32 }, %)', + expectFinal: 'angledLine({ angle = angle001, length = len001 }, %)', + ang: ang + 180, + locator: '[data-overlay-toolbar-index="1"]', + }) + + await page.mouse.move(700, 250) + await page.waitForTimeout(100) + + let lineTo = await u.getBoundingBox('[data-overlay-index="2"]') + ang = await u.getAngle('[data-overlay-index="2"]') + console.log('lineTo1') + await clickConstrained({ + hoverPos: { x: lineTo.x, y: lineTo.y }, + constraintType: 'yAbsolute', + expectBeforeUnconstrained: + 'line(endAbsolute = [5 + 33, 20 + 11.5 + 0])', + expectAfterUnconstrained: 'line(endAbsolute = [5 + 33, 31.5])', + expectFinal: 'line(endAbsolute = [5 + 33, yAbs001])', + steps: 8, + ang: ang + 180, + locator: '[data-overlay-toolbar-index="2"]', + }) + console.log('lineTo2') + await clickConstrained({ + hoverPos: { x: lineTo.x, y: lineTo.y }, + constraintType: 'xAbsolute', + expectBeforeUnconstrained: 'line(endAbsolute = [5 + 33, yAbs001])', + expectAfterUnconstrained: 'line(endAbsolute = [38, yAbs001])', + expectFinal: 'line(endAbsolute = [xAbs001, yAbs001])', + steps: 8, + ang: ang + 180, + locator: '[data-overlay-toolbar-index="2"]', + }) + + const xLineTo = await u.getBoundingBox('[data-overlay-index="3"]') + ang = await u.getAngle('[data-overlay-index="3"]') + console.log('xlineTo1') + await clickConstrained({ + hoverPos: { x: xLineTo.x, y: xLineTo.y }, + constraintType: 'xAbsolute', + expectBeforeUnconstrained: 'xLine(endAbsolute = 5 + 9 - 5)', + expectAfterUnconstrained: 'xLine(endAbsolute = 9)', + expectFinal: 'xLine(endAbsolute = xAbs002)', + ang: ang + 180, + steps: 8, + locator: '[data-overlay-toolbar-index="3"]', + }) + }) + + // Broken on main at time of writing! + test('for segments [yLineTo, xLine]', async ({ + page, + editor, + homePage, + }) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') + await page.addInitScript(async () => { + localStorage.setItem( + 'persistCode', + `yRel001 = -14 xRel001 = 0.5 angle001 = 3 len001 = 32 @@ -392,69 +393,68 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { |> yLine(length = 21.14 + 0) |> angledLineOfXLength({ angle = 181 + 0, length = 23.14 }, %) ` - ) - }) - const u = await getUtils(page) - await page.setBodyDimensions({ width: 1200, height: 500 }) + ) + }) + const u = await getUtils(page) + await page.setBodyDimensions({ width: 1200, height: 500 }) - await homePage.goToModelingScene() + await homePage.goToModelingScene() - // wait for execution done - await u.openDebugPanel() - await u.expectCmdLog('[data-message-type="execution-done"]') - await u.closeDebugPanel() + // wait for execution done + await u.openDebugPanel() + await u.expectCmdLog('[data-message-type="execution-done"]') + await u.closeDebugPanel() - await page.getByText('xLine(length = 26.04)').click() - await page.waitForTimeout(100) - await page.getByRole('button', { name: 'Edit Sketch' }).click() - await page.waitForTimeout(500) + await page.getByText('xLine(length = 26.04)').click() + await page.waitForTimeout(100) + await page.getByRole('button', { name: 'Edit Sketch' }).click() + await page.waitForTimeout(500) - await expect(page.getByTestId('segment-overlay')).toHaveCount(8) + await expect(page.getByTestId('segment-overlay')).toHaveCount(8) - const clickUnconstrained = _clickUnconstrained(page, editor) + const clickUnconstrained = _clickUnconstrained(page, editor) - await page.mouse.move(700, 250) - await page.waitForTimeout(100) + await page.mouse.move(700, 250) + await page.waitForTimeout(100) - let ang = 0 + let ang = 0 - const yLineTo = await u.getBoundingBox('[data-overlay-index="4"]') - ang = await u.getAngle('[data-overlay-index="4"]') - console.log('ylineTo1') - await clickUnconstrained({ - hoverPos: { x: yLineTo.x, y: yLineTo.y - 200 }, - constraintType: 'yAbsolute', - expectBeforeUnconstrained: 'yLine(endAbsolute = -10.77, tag = $a)', - expectAfterUnconstrained: 'yLine(endAbsolute = yAbs002, tag = $a)', - expectFinal: 'yLine(endAbsolute = -10.77, tag = $a)', - ang: ang + 180, - locator: '[data-overlay-toolbar-index="4"]', - }) + const yLineTo = await u.getBoundingBox('[data-overlay-index="4"]') + ang = await u.getAngle('[data-overlay-index="4"]') + console.log('ylineTo1') + await clickUnconstrained({ + hoverPos: { x: yLineTo.x, y: yLineTo.y - 200 }, + constraintType: 'yAbsolute', + expectBeforeUnconstrained: 'yLine(endAbsolute = -10.77, tag = $a)', + expectAfterUnconstrained: 'yLine(endAbsolute = yAbs002, tag = $a)', + expectFinal: 'yLine(endAbsolute = -10.77, tag = $a)', + ang: ang + 180, + locator: '[data-overlay-toolbar-index="4"]', + }) - const xLine = await u.getBoundingBox('[data-overlay-index="5"]') - ang = await u.getAngle('[data-overlay-index="5"]') - console.log('xline') - await clickUnconstrained({ - hoverPos: { x: xLine.x, y: xLine.y }, - constraintType: 'xRelative', - expectBeforeUnconstrained: 'xLine(length = 26.04)', - expectAfterUnconstrained: 'xLine(length = xRel002)', - expectFinal: 'xLine(length = 26.04)', - steps: 10, - ang: ang + 180, - locator: '[data-overlay-toolbar-index="5"]', - }) - } - ) - test('for segments [yLine, angledLineOfXLength, angledLineOfYLength]', async ({ - page, - editor, - homePage, - }) => { - await page.addInitScript(async () => { - localStorage.setItem( - 'persistCode', - `part001 = startSketchOn('XZ') + const xLine = await u.getBoundingBox('[data-overlay-index="5"]') + ang = await u.getAngle('[data-overlay-index="5"]') + console.log('xline') + await clickUnconstrained({ + hoverPos: { x: xLine.x, y: xLine.y }, + constraintType: 'xRelative', + expectBeforeUnconstrained: 'xLine(length = 26.04)', + expectAfterUnconstrained: 'xLine(length = xRel002)', + expectFinal: 'xLine(length = 26.04)', + steps: 10, + ang: ang + 180, + locator: '[data-overlay-toolbar-index="5"]', + }) + }) + test('for segments [yLine, angledLineOfXLength, angledLineOfYLength]', async ({ + page, + editor, + homePage, + }) => { + await page.addInitScript(async () => { + localStorage.setItem( + 'persistCode', + `part001 = startSketchOn('XZ') |> startProfileAt([0, 0], %) |> line(end = [0.5, -14 + 0]) |> angledLine({ angle = 3 + 0, length = 32 + 0 }, %) @@ -474,119 +474,118 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { }, %) |> tangentialArcTo([3.14 + 13, 3.14], %) ` - ) - localStorage.setItem('disableAxis', 'true') - }) - const u = await getUtils(page) - await page.setBodyDimensions({ width: 1200, height: 500 }) - - await homePage.goToModelingScene() - - // wait for execution done - await u.openDebugPanel() - await u.expectCmdLog('[data-message-type="execution-done"]') - await u.closeDebugPanel() - await page.waitForTimeout(500) - - await page.getByText('xLine(endAbsolute = 9 - 5)').click() - await page.waitForTimeout(100) - await page.getByRole('button', { name: 'Edit Sketch' }).click() - await page.waitForTimeout(500) - - await expect(page.getByTestId('segment-overlay')).toHaveCount(13) - - const clickUnconstrained = _clickUnconstrained(page, editor) - const clickConstrained = _clickConstrained(page, editor) - - let ang = 0 - - const yLine = await u.getBoundingBox('[data-overlay-index="6"]') - ang = await u.getAngle('[data-overlay-index="6"]') - console.log('yline1') - await clickConstrained({ - hoverPos: { x: yLine.x, y: yLine.y }, - constraintType: 'yRelative', - expectBeforeUnconstrained: 'yLine(length = 21.14 + 0)', - expectAfterUnconstrained: 'yLine(length = 21.14)', - expectFinal: 'yLine(length = yRel001)', - ang: ang + 180, - locator: '[data-overlay-toolbar-index="6"]', - }) - - const angledLineOfXLength = await u.getBoundingBox( - '[data-overlay-index="7"]' ) - ang = await u.getAngle('[data-overlay-index="7"]') - console.log('angledLineOfXLength1') - await clickConstrained({ - hoverPos: { x: angledLineOfXLength.x, y: angledLineOfXLength.y }, - constraintType: 'angle', - expectBeforeUnconstrained: - 'angledLineOfXLength({ angle = 181 + 0, length = 23.14 }, %)', - expectAfterUnconstrained: - 'angledLineOfXLength({ angle = -179, length = 23.14 }, %)', - expectFinal: - 'angledLineOfXLength({ angle = angle001, length = 23.14 }, %)', - ang: ang + 180, - locator: '[data-overlay-toolbar-index="7"]', - }) - console.log('angledLineOfXLength2') - await clickUnconstrained({ - hoverPos: { x: angledLineOfXLength.x, y: angledLineOfXLength.y }, - constraintType: 'xRelative', - expectBeforeUnconstrained: - 'angledLineOfXLength({ angle = angle001, length = 23.14 }, %)', - expectAfterUnconstrained: - 'angledLineOfXLength({ angle = angle001, length = xRel001 }, %)', - expectFinal: - 'angledLineOfXLength({ angle = angle001, length = 23.14 }, %)', - steps: 7, - ang: ang + 180, - locator: '[data-overlay-toolbar-index="7"]', - }) - - const angledLineOfYLength = await u.getBoundingBox( - '[data-overlay-index="8"]' - ) - ang = await u.getAngle('[data-overlay-index="8"]') - console.log('angledLineOfYLength1') - await clickUnconstrained({ - hoverPos: { x: angledLineOfYLength.x, y: angledLineOfYLength.y }, - constraintType: 'angle', - expectBeforeUnconstrained: - 'angledLineOfYLength({ angle = -91, length = 19 + 0 }, %)', - expectAfterUnconstrained: - 'angledLineOfYLength({ angle = angle002, length = 19 + 0 }, %)', - expectFinal: - 'angledLineOfYLength({ angle = -91, length = 19 + 0 }, %)', - ang: ang + 180, - steps: 6, - locator: '[data-overlay-toolbar-index="8"]', - }) - console.log('angledLineOfYLength2') - await clickConstrained({ - hoverPos: { x: angledLineOfYLength.x, y: angledLineOfYLength.y }, - constraintType: 'yRelative', - expectBeforeUnconstrained: - 'angledLineOfYLength({ angle = -91, length = 19 + 0 }, %)', - expectAfterUnconstrained: - 'angledLineOfYLength({ angle = -91, length = 19 }, %)', - expectFinal: - 'angledLineOfYLength({ angle = -91, length = yRel002 }, %)', - ang: ang + 180, - steps: 7, - locator: '[data-overlay-toolbar-index="8"]', - }) + localStorage.setItem('disableAxis', 'true') }) - test('for segments [angledLineToX, angledLineToY, angledLineThatIntersects]', async ({ - page, - editor, - homePage, - }) => { - await page.addInitScript(async () => { - localStorage.setItem( - 'persistCode', - `part001 = startSketchOn('XZ') + const u = await getUtils(page) + await page.setBodyDimensions({ width: 1200, height: 500 }) + + await homePage.goToModelingScene() + + // wait for execution done + await u.openDebugPanel() + await u.expectCmdLog('[data-message-type="execution-done"]') + await u.closeDebugPanel() + await page.waitForTimeout(500) + + await page.getByText('xLine(endAbsolute = 9 - 5)').click() + await page.waitForTimeout(100) + await page.getByRole('button', { name: 'Edit Sketch' }).click() + await page.waitForTimeout(500) + + await expect(page.getByTestId('segment-overlay')).toHaveCount(13) + + const clickUnconstrained = _clickUnconstrained(page, editor) + const clickConstrained = _clickConstrained(page, editor) + + let ang = 0 + + const yLine = await u.getBoundingBox('[data-overlay-index="6"]') + ang = await u.getAngle('[data-overlay-index="6"]') + console.log('yline1') + await clickConstrained({ + hoverPos: { x: yLine.x, y: yLine.y }, + constraintType: 'yRelative', + expectBeforeUnconstrained: 'yLine(length = 21.14 + 0)', + expectAfterUnconstrained: 'yLine(length = 21.14)', + expectFinal: 'yLine(length = yRel001)', + ang: ang + 180, + locator: '[data-overlay-toolbar-index="6"]', + }) + + const angledLineOfXLength = await u.getBoundingBox( + '[data-overlay-index="7"]' + ) + ang = await u.getAngle('[data-overlay-index="7"]') + console.log('angledLineOfXLength1') + await clickConstrained({ + hoverPos: { x: angledLineOfXLength.x, y: angledLineOfXLength.y }, + constraintType: 'angle', + expectBeforeUnconstrained: + 'angledLineOfXLength({ angle = 181 + 0, length = 23.14 }, %)', + expectAfterUnconstrained: + 'angledLineOfXLength({ angle = -179, length = 23.14 }, %)', + expectFinal: + 'angledLineOfXLength({ angle = angle001, length = 23.14 }, %)', + ang: ang + 180, + locator: '[data-overlay-toolbar-index="7"]', + }) + console.log('angledLineOfXLength2') + await clickUnconstrained({ + hoverPos: { x: angledLineOfXLength.x, y: angledLineOfXLength.y }, + constraintType: 'xRelative', + expectBeforeUnconstrained: + 'angledLineOfXLength({ angle = angle001, length = 23.14 }, %)', + expectAfterUnconstrained: + 'angledLineOfXLength({ angle = angle001, length = xRel001 }, %)', + expectFinal: + 'angledLineOfXLength({ angle = angle001, length = 23.14 }, %)', + steps: 7, + ang: ang + 180, + locator: '[data-overlay-toolbar-index="7"]', + }) + + const angledLineOfYLength = await u.getBoundingBox( + '[data-overlay-index="8"]' + ) + ang = await u.getAngle('[data-overlay-index="8"]') + console.log('angledLineOfYLength1') + await clickUnconstrained({ + hoverPos: { x: angledLineOfYLength.x, y: angledLineOfYLength.y }, + constraintType: 'angle', + expectBeforeUnconstrained: + 'angledLineOfYLength({ angle = -91, length = 19 + 0 }, %)', + expectAfterUnconstrained: + 'angledLineOfYLength({ angle = angle002, length = 19 + 0 }, %)', + expectFinal: 'angledLineOfYLength({ angle = -91, length = 19 + 0 }, %)', + ang: ang + 180, + steps: 6, + locator: '[data-overlay-toolbar-index="8"]', + }) + console.log('angledLineOfYLength2') + await clickConstrained({ + hoverPos: { x: angledLineOfYLength.x, y: angledLineOfYLength.y }, + constraintType: 'yRelative', + expectBeforeUnconstrained: + 'angledLineOfYLength({ angle = -91, length = 19 + 0 }, %)', + expectAfterUnconstrained: + 'angledLineOfYLength({ angle = -91, length = 19 }, %)', + expectFinal: + 'angledLineOfYLength({ angle = -91, length = yRel002 }, %)', + ang: ang + 180, + steps: 7, + locator: '[data-overlay-toolbar-index="8"]', + }) + }) + test('for segments [angledLineToX, angledLineToY, angledLineThatIntersects]', async ({ + page, + editor, + homePage, + }) => { + await page.addInitScript(async () => { + localStorage.setItem( + 'persistCode', + `part001 = startSketchOn('XZ') |> startProfileAt([0, 0], %) |> line(end = [0.5, -14 + 0]) |> angledLine({ angle = 3 + 0, length = 32 + 0 }, %) @@ -606,151 +605,148 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { }, %) |> tangentialArcTo([3.14 + 13, 1.14], %) ` - ) - localStorage.setItem('disableAxis', 'true') - }) - const u = await getUtils(page) - await page.setBodyDimensions({ width: 1200, height: 500 }) - - await homePage.goToModelingScene() - - // wait for execution done - await u.openDebugPanel() - await u.expectCmdLog('[data-message-type="execution-done"]') - await u.closeDebugPanel() - - await page.getByText('xLine(endAbsolute = 9 - 5)').click() - await page.waitForTimeout(100) - await page.getByRole('button', { name: 'Edit Sketch' }).click() - await page.waitForTimeout(500) - - await expect(page.getByTestId('segment-overlay')).toHaveCount(13) - - const clickUnconstrained = _clickUnconstrained(page, editor) - const clickConstrained = _clickConstrained(page, editor) - - let ang = 0 - - const angledLineToX = await u.getBoundingBox('[data-overlay-index="9"]') - ang = await u.getAngle('[data-overlay-index="9"]') - console.log('angledLineToX') - await clickConstrained({ - hoverPos: { x: angledLineToX.x, y: angledLineToX.y }, - constraintType: 'angle', - expectBeforeUnconstrained: - 'angledLineToX({ angle = 3 + 0, to = 26 }, %)', - expectAfterUnconstrained: 'angledLineToX({ angle = 3, to = 26 }, %)', - expectFinal: 'angledLineToX({ angle = angle001, to = 26 }, %)', - ang: ang + 180, - locator: '[data-overlay-toolbar-index="9"]', - }) - console.log('angledLineToX2') - await clickUnconstrained({ - hoverPos: { x: angledLineToX.x, y: angledLineToX.y }, - constraintType: 'xAbsolute', - expectBeforeUnconstrained: - 'angledLineToX({ angle = angle001, to = 26 }, %)', - expectAfterUnconstrained: - 'angledLineToX({ angle = angle001, to = xAbs001 }, %)', - expectFinal: 'angledLineToX({ angle = angle001, to = 26 }, %)', - ang: ang + 180, - locator: '[data-overlay-toolbar-index="9"]', - }) - - const angledLineToY = await u.getBoundingBox( - '[data-overlay-index="10"]' ) - ang = await u.getAngle('[data-overlay-index="10"]') - console.log('angledLineToY') - await clickUnconstrained({ - hoverPos: { x: angledLineToY.x, y: angledLineToY.y }, - constraintType: 'angle', - expectBeforeUnconstrained: - 'angledLineToY({ angle = 89, to = 9.14 + 0 }, %)', - expectAfterUnconstrained: - 'angledLineToY({ angle = angle002, to = 9.14 + 0 }, %)', - expectFinal: 'angledLineToY({ angle = 89, to = 9.14 + 0 }, %)', - steps: process.platform === 'darwin' ? 8 : 9, - ang: ang + 180, - locator: '[data-overlay-toolbar-index="10"]', - }) - console.log('angledLineToY2') - await clickConstrained({ - hoverPos: { x: angledLineToY.x, y: angledLineToY.y }, - constraintType: 'yAbsolute', - expectBeforeUnconstrained: - 'angledLineToY({ angle = 89, to = 9.14 + 0 }, %)', - expectAfterUnconstrained: - 'angledLineToY({ angle = 89, to = 9.14 }, %)', - expectFinal: 'angledLineToY({ angle = 89, to = yAbs001 }, %)', - ang: ang + 180, - locator: '[data-overlay-toolbar-index="10"]', - }) + localStorage.setItem('disableAxis', 'true') + }) + const u = await getUtils(page) + await page.setBodyDimensions({ width: 1200, height: 500 }) - const angledLineThatIntersects = await u.getBoundingBox( - '[data-overlay-index="11"]' - ) - ang = await u.getAngle('[data-overlay-index="11"]') - console.log('angledLineThatIntersects') - await clickUnconstrained({ - hoverPos: { - x: angledLineThatIntersects.x, - y: angledLineThatIntersects.y, - }, - constraintType: 'angle', - expectBeforeUnconstrained: `angledLineThatIntersects({ + await homePage.goToModelingScene() + + // wait for execution done + await u.openDebugPanel() + await u.expectCmdLog('[data-message-type="execution-done"]') + await u.closeDebugPanel() + + await page.getByText('xLine(endAbsolute = 9 - 5)').click() + await page.waitForTimeout(100) + await page.getByRole('button', { name: 'Edit Sketch' }).click() + await page.waitForTimeout(500) + + await expect(page.getByTestId('segment-overlay')).toHaveCount(13) + + const clickUnconstrained = _clickUnconstrained(page, editor) + const clickConstrained = _clickConstrained(page, editor) + + let ang = 0 + + const angledLineToX = await u.getBoundingBox('[data-overlay-index="9"]') + ang = await u.getAngle('[data-overlay-index="9"]') + console.log('angledLineToX') + await clickConstrained({ + hoverPos: { x: angledLineToX.x, y: angledLineToX.y }, + constraintType: 'angle', + expectBeforeUnconstrained: + 'angledLineToX({ angle = 3 + 0, to = 26 }, %)', + expectAfterUnconstrained: 'angledLineToX({ angle = 3, to = 26 }, %)', + expectFinal: 'angledLineToX({ angle = angle001, to = 26 }, %)', + ang: ang + 180, + locator: '[data-overlay-toolbar-index="9"]', + }) + console.log('angledLineToX2') + await clickUnconstrained({ + hoverPos: { x: angledLineToX.x, y: angledLineToX.y }, + constraintType: 'xAbsolute', + expectBeforeUnconstrained: + 'angledLineToX({ angle = angle001, to = 26 }, %)', + expectAfterUnconstrained: + 'angledLineToX({ angle = angle001, to = xAbs001 }, %)', + expectFinal: 'angledLineToX({ angle = angle001, to = 26 }, %)', + ang: ang + 180, + locator: '[data-overlay-toolbar-index="9"]', + }) + + const angledLineToY = await u.getBoundingBox('[data-overlay-index="10"]') + ang = await u.getAngle('[data-overlay-index="10"]') + console.log('angledLineToY') + await clickUnconstrained({ + hoverPos: { x: angledLineToY.x, y: angledLineToY.y }, + constraintType: 'angle', + expectBeforeUnconstrained: + 'angledLineToY({ angle = 89, to = 9.14 + 0 }, %)', + expectAfterUnconstrained: + 'angledLineToY({ angle = angle002, to = 9.14 + 0 }, %)', + expectFinal: 'angledLineToY({ angle = 89, to = 9.14 + 0 }, %)', + steps: process.platform === 'darwin' ? 8 : 9, + ang: ang + 180, + locator: '[data-overlay-toolbar-index="10"]', + }) + console.log('angledLineToY2') + await clickConstrained({ + hoverPos: { x: angledLineToY.x, y: angledLineToY.y }, + constraintType: 'yAbsolute', + expectBeforeUnconstrained: + 'angledLineToY({ angle = 89, to = 9.14 + 0 }, %)', + expectAfterUnconstrained: 'angledLineToY({ angle = 89, to = 9.14 }, %)', + expectFinal: 'angledLineToY({ angle = 89, to = yAbs001 }, %)', + ang: ang + 180, + locator: '[data-overlay-toolbar-index="10"]', + }) + + const angledLineThatIntersects = await u.getBoundingBox( + '[data-overlay-index="11"]' + ) + ang = await u.getAngle('[data-overlay-index="11"]') + console.log('angledLineThatIntersects') + await clickUnconstrained({ + hoverPos: { + x: angledLineThatIntersects.x, + y: angledLineThatIntersects.y, + }, + constraintType: 'angle', + expectBeforeUnconstrained: `angledLineThatIntersects({ angle = 4.14, intersectTag = a, offset = 9 }, %)`, - expectAfterUnconstrained: `angledLineThatIntersects({ + expectAfterUnconstrained: `angledLineThatIntersects({ angle = angle003, intersectTag = a, offset = 9 }, %)`, - expectFinal: `angledLineThatIntersects({ + expectFinal: `angledLineThatIntersects({ angle = -176, offset = 9, intersectTag = a }, %)`, - ang: ang + 180, - locator: '[data-overlay-toolbar-index="11"]', - }) - console.log('angledLineThatIntersects2') - await clickUnconstrained({ - hoverPos: { - x: angledLineThatIntersects.x, - y: angledLineThatIntersects.y, - }, - constraintType: 'intersectionOffset', - expectBeforeUnconstrained: `angledLineThatIntersects({ + ang: ang + 180, + locator: '[data-overlay-toolbar-index="11"]', + }) + console.log('angledLineThatIntersects2') + await clickUnconstrained({ + hoverPos: { + x: angledLineThatIntersects.x, + y: angledLineThatIntersects.y, + }, + constraintType: 'intersectionOffset', + expectBeforeUnconstrained: `angledLineThatIntersects({ angle = -176, offset = 9, intersectTag = a }, %)`, - expectAfterUnconstrained: `angledLineThatIntersects({ + expectAfterUnconstrained: `angledLineThatIntersects({ angle = -176, offset = perpDist001, intersectTag = a }, %)`, - expectFinal: `angledLineThatIntersects({ + expectFinal: `angledLineThatIntersects({ angle = -176, offset = 9, intersectTag = a }, %)`, - ang: ang + 180, - locator: '[data-overlay-toolbar-index="11"]', - }) + ang: ang + 180, + locator: '[data-overlay-toolbar-index="11"]', }) - test('for segment [tangentialArcTo]', async ({ - page, - editor, - homePage, - }) => { - await page.addInitScript(async () => { - localStorage.setItem( - 'persistCode', - `part001 = startSketchOn('XZ') + }) + test('for segment [tangentialArcTo]', async ({ + page, + editor, + homePage, + }) => { + await page.addInitScript(async () => { + localStorage.setItem( + 'persistCode', + `part001 = startSketchOn('XZ') |> startProfileAt([0, 0], %) |> line(end = [0.5, -14 + 0]) |> angledLine({ angle = 3 + 0, length = 32 + 0 }, %) @@ -770,67 +766,67 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { }, %) |> tangentialArcTo([3.14 + 13, -3.14], %) ` - ) - localStorage.setItem('disableAxis', 'true') - }) - const u = await getUtils(page) - await page.setBodyDimensions({ width: 1200, height: 500 }) - - await homePage.goToModelingScene() - - // wait for execution done - await u.openDebugPanel() - await u.expectCmdLog('[data-message-type="execution-done"]') - await u.closeDebugPanel() - - await page.getByText('xLine(endAbsolute = 9 - 5)').click() - await page.waitForTimeout(100) - await page.getByRole('button', { name: 'Edit Sketch' }).click() - await page.waitForTimeout(500) - - await expect(page.getByTestId('segment-overlay')).toHaveCount(13) - - const clickUnconstrained = _clickUnconstrained(page, editor) - const clickConstrained = _clickConstrained(page, editor) - - const tangentialArcTo = await u.getBoundingBox( - '[data-overlay-index="12"]' ) - let ang = await u.getAngle('[data-overlay-index="12"]') - console.log('tangentialArcTo') - await clickConstrained({ - hoverPos: { x: tangentialArcTo.x, y: tangentialArcTo.y }, - constraintType: 'xAbsolute', - expectBeforeUnconstrained: 'tangentialArcTo([3.14 + 13, -3.14], %)', - expectAfterUnconstrained: 'tangentialArcTo([16.14, -3.14], %)', - expectFinal: 'tangentialArcTo([xAbs001, -3.14], %)', - ang: ang + 180, - steps: 6, - locator: '[data-overlay-toolbar-index="12"]', - }) - console.log('tangentialArcTo2') - await clickUnconstrained({ - hoverPos: { x: tangentialArcTo.x, y: tangentialArcTo.y }, - constraintType: 'yAbsolute', - expectBeforeUnconstrained: 'tangentialArcTo([xAbs001, -3.14], %)', - expectAfterUnconstrained: 'tangentialArcTo([xAbs001, yAbs001], %)', - expectFinal: 'tangentialArcTo([xAbs001, -3.14], %)', - ang: ang + 180, - steps: 10, - locator: '[data-overlay-toolbar-index="12"]', - }) + localStorage.setItem('disableAxis', 'true') }) - test('for segment [arcTo]', async ({ - page, - editor, - homePage, - scene, - cmdBar, - }) => { - await page.addInitScript(async () => { - localStorage.setItem( - 'persistCode', - `sketch001 = startSketchOn('XZ') + const u = await getUtils(page) + await page.setBodyDimensions({ width: 1200, height: 500 }) + + await homePage.goToModelingScene() + + // wait for execution done + await u.openDebugPanel() + await u.expectCmdLog('[data-message-type="execution-done"]') + await u.closeDebugPanel() + + await page.getByText('xLine(endAbsolute = 9 - 5)').click() + await page.waitForTimeout(100) + await page.getByRole('button', { name: 'Edit Sketch' }).click() + await page.waitForTimeout(500) + + await expect(page.getByTestId('segment-overlay')).toHaveCount(13) + + const clickUnconstrained = _clickUnconstrained(page, editor) + const clickConstrained = _clickConstrained(page, editor) + + const tangentialArcTo = await u.getBoundingBox( + '[data-overlay-index="12"]' + ) + let ang = await u.getAngle('[data-overlay-index="12"]') + console.log('tangentialArcTo') + await clickConstrained({ + hoverPos: { x: tangentialArcTo.x, y: tangentialArcTo.y }, + constraintType: 'xAbsolute', + expectBeforeUnconstrained: 'tangentialArcTo([3.14 + 13, -3.14], %)', + expectAfterUnconstrained: 'tangentialArcTo([16.14, -3.14], %)', + expectFinal: 'tangentialArcTo([xAbs001, -3.14], %)', + ang: ang + 180, + steps: 6, + locator: '[data-overlay-toolbar-index="12"]', + }) + console.log('tangentialArcTo2') + await clickUnconstrained({ + hoverPos: { x: tangentialArcTo.x, y: tangentialArcTo.y }, + constraintType: 'yAbsolute', + expectBeforeUnconstrained: 'tangentialArcTo([xAbs001, -3.14], %)', + expectAfterUnconstrained: 'tangentialArcTo([xAbs001, yAbs001], %)', + expectFinal: 'tangentialArcTo([xAbs001, -3.14], %)', + ang: ang + 180, + steps: 10, + locator: '[data-overlay-toolbar-index="12"]', + }) + }) + test('for segment [arcTo]', async ({ + page, + editor, + homePage, + scene, + cmdBar, + }) => { + await page.addInitScript(async () => { + localStorage.setItem( + 'persistCode', + `sketch001 = startSketchOn('XZ') profile001 = startProfileAt([56.37, 120.33], sketch001) |> line(end = [162.86, 106.48]) |> arcTo({ @@ -844,187 +840,184 @@ profile001 = startProfileAt([56.37, 120.33], sketch001) angleEnd = -141.07 }, %) ` - ) - localStorage.setItem('disableAxis', 'true') - }) - const u = await getUtils(page) - await page.setBodyDimensions({ width: 1200, height: 500 }) + ) + localStorage.setItem('disableAxis', 'true') + }) + const u = await getUtils(page) + await page.setBodyDimensions({ width: 1200, height: 500 }) - await homePage.goToModelingScene() - await scene.connectionEstablished() - await scene.settled(cmdBar) + await homePage.goToModelingScene() + await scene.connectionEstablished() + await scene.settled(cmdBar) - // wait for execution done + // wait for execution done - await page.getByText('line(end = [162.86, 106.48])').click() - await page.waitForTimeout(100) - await page.getByRole('button', { name: 'Edit Sketch' }).click() - await page.waitForTimeout(500) + await page.getByText('line(end = [162.86, 106.48])').click() + await page.waitForTimeout(100) + await page.getByRole('button', { name: 'Edit Sketch' }).click() + await page.waitForTimeout(500) - await expect(page.getByTestId('segment-overlay')).toHaveCount(5) + await expect(page.getByTestId('segment-overlay')).toHaveCount(5) - const clickUnconstrained = _clickUnconstrained(page, editor) - const clickConstrained = _clickConstrained(page, editor) + const clickUnconstrained = _clickUnconstrained(page, editor) + const clickConstrained = _clickConstrained(page, editor) - const arcTo = await u.getBoundingBox('[data-overlay-index="1"]') - let ang = await u.getAngle('[data-overlay-index="1"]') - console.log('arcTo interior x') - await clickUnconstrained({ - hoverPos: { x: arcTo.x, y: arcTo.y }, - constraintType: 'xAbsolute', - expectBeforeUnconstrained: `arcTo({ + const arcTo = await u.getBoundingBox('[data-overlay-index="1"]') + let ang = await u.getAngle('[data-overlay-index="1"]') + console.log('arcTo interior x') + await clickUnconstrained({ + hoverPos: { x: arcTo.x, y: arcTo.y }, + constraintType: 'xAbsolute', + expectBeforeUnconstrained: `arcTo({ interior = [360.16, 231.76], end = [391.48, 131.54] }, %)`, - expectAfterUnconstrained: `arcTo({ + expectAfterUnconstrained: `arcTo({ interior = [360.16, 231.76], end = [391.48, 131.54] }, %)`, - expectFinal: `arcTo({ + expectFinal: `arcTo({ interior = [xAbs001, 231.76], end = [391.48, 131.54] }, %)`, - ang: ang, - steps: 6, - locator: '[data-overlay-toolbar-index="1"]', - }) + ang: ang, + steps: 6, + locator: '[data-overlay-toolbar-index="1"]', + }) - console.log('arcTo interior y') - await clickUnconstrained({ - hoverPos: { x: arcTo.x, y: arcTo.y }, - constraintType: 'yAbsolute', - expectBeforeUnconstrained: `arcTo({ + console.log('arcTo interior y') + await clickUnconstrained({ + hoverPos: { x: arcTo.x, y: arcTo.y }, + constraintType: 'yAbsolute', + expectBeforeUnconstrained: `arcTo({ interior = [xAbs001, 231.76], end = [391.48, 131.54] }, %)`, - expectAfterUnconstrained: `arcTo({ + expectAfterUnconstrained: `arcTo({ interior = [xAbs001, yAbs001], end = [391.48, 131.54] }, %)`, - expectFinal: `arcTo({ + expectFinal: `arcTo({ interior = [xAbs001, 231.76], end = [391.48, 131.54] }, %)`, - ang: ang, - steps: 10, - locator: '[data-overlay-toolbar-index="1"]', - }) + ang: ang, + steps: 10, + locator: '[data-overlay-toolbar-index="1"]', + }) - console.log('arcTo end x') - await clickConstrained({ - hoverPos: { x: arcTo.x, y: arcTo.y }, - constraintType: 'xAbsolute', - expectBeforeUnconstrained: `arcTo({ + console.log('arcTo end x') + await clickConstrained({ + hoverPos: { x: arcTo.x, y: arcTo.y }, + constraintType: 'xAbsolute', + expectBeforeUnconstrained: `arcTo({ interior = [xAbs001, 231.76], end = [391.48, 131.54] }, %)`, - expectAfterUnconstrained: `arcTo({ + expectAfterUnconstrained: `arcTo({ interior = [xAbs001, 231.76], end = [391.48, 131.54] }, %)`, - expectFinal: `arcTo({ + expectFinal: `arcTo({ interior = [xAbs001, 231.76], end = [xAbs002, 131.54] }, %)`, - ang: ang + 180, - steps: 6, - locator: '[data-overlay-toolbar-index="1"]', - }) + ang: ang + 180, + steps: 6, + locator: '[data-overlay-toolbar-index="1"]', + }) - console.log('arcTo end y') - await clickUnconstrained({ - hoverPos: { x: arcTo.x, y: arcTo.y }, - constraintType: 'yAbsolute', - expectBeforeUnconstrained: `arcTo({ + console.log('arcTo end y') + await clickUnconstrained({ + hoverPos: { x: arcTo.x, y: arcTo.y }, + constraintType: 'yAbsolute', + expectBeforeUnconstrained: `arcTo({ interior = [xAbs001, 231.76], end = [xAbs002, 131.54] }, %)`, - expectAfterUnconstrained: `arcTo({ + expectAfterUnconstrained: `arcTo({ interior = [xAbs001, 231.76], end = [xAbs002, yAbs002] }, %)`, - expectFinal: `arcTo({ + expectFinal: `arcTo({ interior = [xAbs001, 231.76], end = [xAbs002, 131.54] }, %)`, - ang: ang + 180, - steps: 10, - locator: '[data-overlay-toolbar-index="1"]', - }) + ang: ang + 180, + steps: 10, + locator: '[data-overlay-toolbar-index="1"]', }) - test('for segment [circle]', async ({ page, editor, homePage }) => { - await page.addInitScript(async () => { - localStorage.setItem( - 'persistCode', - `part001 = startSketchOn('XZ') + }) + test('for segment [circle]', async ({ page, editor, homePage }) => { + await page.addInitScript(async () => { + localStorage.setItem( + 'persistCode', + `part001 = startSketchOn('XZ') |> circle(center = [1 + 0, 0], radius = 8) ` - ) - localStorage.setItem('disableAxis', 'true') - }) - const u = await getUtils(page) - await page.setBodyDimensions({ width: 1200, height: 500 }) - - await homePage.goToModelingScene() - - // 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, editor) - const clickConstrained = _clickConstrained(page, editor) - - 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 + 180, - steps: 30, - 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"]', - }) + ) + localStorage.setItem('disableAxis', 'true') }) - } - ) + const u = await getUtils(page) + await page.setBodyDimensions({ width: 1200, height: 500 }) + + await homePage.goToModelingScene() + + // 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, editor) + const clickConstrained = _clickConstrained(page, editor) + + 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 + 180, + steps: 30, + 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 = (page: Page, editor: EditorFixture) => @@ -1357,7 +1350,7 @@ profile001 = startProfileAt([56.37, 120.33], sketch001) |> startProfileAt([5, 6], %) |> ${lineToBeDeleted} |> line(end = [-10, -15]) - |> angledLine([-176, segLen(seg01)], %) + |> angledLine([-176, segLen(seg01)], %) ${extraLine ? 'myVar = segLen(seg01)' : ''}` ) }, diff --git a/e2e/playwright/testing-selections.spec.ts b/e2e/playwright/testing-selections.spec.ts index f0199a13b..2c889226c 100644 --- a/e2e/playwright/testing-selections.spec.ts +++ b/e2e/playwright/testing-selections.spec.ts @@ -448,15 +448,20 @@ profile003 = startProfileAt([40.16, -120.48], sketch006) await page.waitForTimeout(200) await expect(u.codeLocator).not.toContainText(codeToBeDeletedSnippet) }) - test.fixme( - 'parent Solid should be select and deletable and uses custom planes to position children', - async ({ page, homePage, scene, cmdBar, editor }) => { - test.setTimeout(90_000) - const u = await getUtils(page) - await page.addInitScript(async () => { - localStorage.setItem( - 'persistCode', - `part001 = startSketchOn('XY') + test('parent Solid should be select and deletable and uses custom planes to position children', async ({ + page, + homePage, + scene, + cmdBar, + editor, + }) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') + test.setTimeout(90_000) + const u = await getUtils(page) + await page.addInitScript(async () => { + localStorage.setItem( + 'persistCode', + `part001 = startSketchOn('XY') yo = startProfileAt([4.83, 12.56], part001) |> line(end = [15.1, 2.48]) |> line(end = [3.15, -9.85], tag = $seg01) @@ -487,35 +492,34 @@ profile001 = startProfileAt([7.49, 9.96], sketch001) |> close() ` - ) - }, KCL_DEFAULT_LENGTH) - await page.setBodyDimensions({ width: 1000, height: 500 }) - - await homePage.goToModelingScene() - await scene.settled(cmdBar) - - const extrudeWall = { x: 575, y: 238 } - - // DELETE with selection on face of parent - await page.mouse.click(extrudeWall.x, extrudeWall.y) - await page.waitForTimeout(100) - await expect(page.locator('.cm-activeLine')).toHaveText( - '|> line(end = [-15.17, -4.1])' ) - await u.openAndClearDebugPanel() - await page.keyboard.press('Delete') - await u.expectCmdLog('[data-message-type="execution-done"]', 10_000) - await page.waitForTimeout(200) + }, KCL_DEFAULT_LENGTH) + await page.setBodyDimensions({ width: 1000, height: 500 }) - await editor.expectEditor.not.toContain(`yoo = extrude(yo, length = 4)`, { - shouldNormalise: true, - }) - await editor.expectEditor.toContain(`startSketchOn({plane={origin`, { - shouldNormalise: true, - }) - await editor.snapshot() - } - ) + await homePage.goToModelingScene() + await scene.settled(cmdBar) + + const extrudeWall = { x: 575, y: 238 } + + // DELETE with selection on face of parent + await page.mouse.click(extrudeWall.x, extrudeWall.y) + await page.waitForTimeout(100) + await expect(page.locator('.cm-activeLine')).toHaveText( + '|> line(end = [-15.17, -4.1])' + ) + await u.openAndClearDebugPanel() + await page.keyboard.press('Delete') + await u.expectCmdLog('[data-message-type="execution-done"]', 10_000) + await page.waitForTimeout(200) + + await editor.expectEditor.not.toContain(`yoo = extrude(yo, length = 4)`, { + shouldNormalise: true, + }) + await editor.expectEditor.toContain(`startSketchOn({plane={origin`, { + shouldNormalise: true, + }) + await editor.snapshot() + }) test('Hovering over 3d features highlights code, clicking puts the cursor in the right place and sends selection id to engine', async ({ page, homePage, diff --git a/e2e/playwright/testing-settings.spec.ts b/e2e/playwright/testing-settings.spec.ts index a266696b6..3ea8003b5 100644 --- a/e2e/playwright/testing-settings.spec.ts +++ b/e2e/playwright/testing-settings.spec.ts @@ -55,91 +55,87 @@ test.describe('Testing settings', () => { }) // The behavior is actually broken. Parent always takes precedence - test.fixme( - 'Project settings can be set and override user settings', - async ({ page, homePage }) => { - const u = await getUtils(page) - await test.step(`Setup`, async () => { - await page.setBodyDimensions({ width: 1200, height: 500 }) - await homePage.goToModelingScene() - await page - .getByRole('button', { name: 'Start Sketch' }) - .waitFor({ state: 'visible' }) - }) - - // Selectors and constants - const paneButtonLocator = page.getByTestId('debug-pane-button') - const headingLocator = page.getByRole('heading', { - name: 'Settings', - exact: true, - }) - const inputLocator = page.locator('input[name="app-showDebugPanel"]') - - await test.step('Open settings dialog and set "Show debug panel" to on', async () => { - await page.keyboard.press('ControlOrMeta+,') - await expect(headingLocator).toBeVisible() - - /** Test to close https://github.com/KittyCAD/modeling-app/issues/2713 */ - await test.step(`Confirm that this dialog has a solid background`, async () => { - await expect - .poll( - () => u.getGreatestPixDiff({ x: 600, y: 250 }, [28, 28, 28]), - { - timeout: 1000, - message: - 'Checking for solid background, should not see default plane colors', - } - ) - .toBeLessThan(15) - }) - - await page.locator('#showDebugPanel').getByText('OffOn').click() - }) - - // Close it and open again with keyboard shortcut, while KCL editor is focused - // Put the cursor in the editor - await test.step('Open settings with keyboard shortcut', async () => { - await page.getByTestId('settings-close-button').click() - await page.locator('.cm-content').click() - await page.keyboard.press('ControlOrMeta+,') - await expect(headingLocator).toBeVisible() - }) - - // Verify the toast appeared - await expect( - page.getByText(`Set show debug panel to "false" for this project`) - ).toBeVisible() - await expect( - page.getByText(`Set show debug panel to "false" for this project`) - ).not.toBeVisible() - - // Check that the debug panel button is gone - await expect(paneButtonLocator).not.toBeVisible() - - // Check that the user setting was not changed - await page.getByRole('radio', { name: 'User' }).click() - await expect(inputLocator).toBeChecked() - - // Roll back to default of "off" - await await page - .getByText( - 'show debug panelRoll back show debug panelRoll back to match' - ) - .hover() + test('Project settings can be set and override user settings', async ({ + page, + homePage, + }) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') + const u = await getUtils(page) + await test.step(`Setup`, async () => { + await page.setBodyDimensions({ width: 1200, height: 500 }) + await homePage.goToModelingScene() await page - .getByRole('button', { - name: 'Roll back show debug panel', - }) - .click() - await expect(inputLocator).not.toBeChecked() + .getByRole('button', { name: 'Start Sketch' }) + .waitFor({ state: 'visible' }) + }) - // Check that the project setting did not change - await page.getByRole('radio', { name: 'Project' }).click() - await expect( - page.locator('input[name="app-showDebugPanel"]') - ).not.toBeChecked() - } - ) + // Selectors and constants + const paneButtonLocator = page.getByTestId('debug-pane-button') + const headingLocator = page.getByRole('heading', { + name: 'Settings', + exact: true, + }) + const inputLocator = page.locator('input[name="app-showDebugPanel"]') + + await test.step('Open settings dialog and set "Show debug panel" to on', async () => { + await page.keyboard.press('ControlOrMeta+,') + await expect(headingLocator).toBeVisible() + + /** Test to close https://github.com/KittyCAD/modeling-app/issues/2713 */ + await test.step(`Confirm that this dialog has a solid background`, async () => { + await expect + .poll(() => u.getGreatestPixDiff({ x: 600, y: 250 }, [28, 28, 28]), { + timeout: 1000, + message: + 'Checking for solid background, should not see default plane colors', + }) + .toBeLessThan(15) + }) + + await page.locator('#showDebugPanel').getByText('OffOn').click() + }) + + // Close it and open again with keyboard shortcut, while KCL editor is focused + // Put the cursor in the editor + await test.step('Open settings with keyboard shortcut', async () => { + await page.getByTestId('settings-close-button').click() + await page.locator('.cm-content').click() + await page.keyboard.press('ControlOrMeta+,') + await expect(headingLocator).toBeVisible() + }) + + // Verify the toast appeared + await expect( + page.getByText(`Set show debug panel to "false" for this project`) + ).toBeVisible() + await expect( + page.getByText(`Set show debug panel to "false" for this project`) + ).not.toBeVisible() + + // Check that the debug panel button is gone + await expect(paneButtonLocator).not.toBeVisible() + + // Check that the user setting was not changed + await page.getByRole('radio', { name: 'User' }).click() + await expect(inputLocator).toBeChecked() + + // Roll back to default of "off" + await await page + .getByText('show debug panelRoll back show debug panelRoll back to match') + .hover() + await page + .getByRole('button', { + name: 'Roll back show debug panel', + }) + .click() + await expect(inputLocator).not.toBeChecked() + + // Check that the project setting did not change + await page.getByRole('radio', { name: 'Project' }).click() + await expect( + page.locator('input[name="app-showDebugPanel"]') + ).not.toBeChecked() + }) test('Keybindings display the correct hotkey for Command Palette', async ({ page, @@ -175,103 +171,98 @@ test.describe('Testing settings', () => { await expect(hotkey).toHaveText(text) }) - test.fixme( - 'Project and user settings can be reset', - async ({ page, homePage }) => { - const u = await getUtils(page) - await test.step(`Setup`, async () => { - await page.setBodyDimensions({ width: 1200, height: 500 }) - await homePage.goToModelingScene() - await u.waitForPageLoad() - await page.waitForTimeout(1000) - }) - - // Selectors and constants - const projectSettingsTab = page.getByRole('radio', { name: 'Project' }) - const userSettingsTab = page.getByRole('radio', { name: 'User' }) - const resetButton = (level: SettingsLevel) => - page.getByRole('button', { - name: `Reset ${level}-level settings`, - }) - const themeColorSetting = page.locator('#themeColor').getByRole('slider') - const settingValues = { - default: '259', - user: '120', - project: '50', - } - const resetToast = (level: SettingsLevel) => - page.getByText(`${level}-level settings were reset`) - - await test.step(`Open the settings modal`, async () => { - await page.getByRole('link', { name: 'Settings' }).last().click() - await expect( - page.getByRole('heading', { name: 'Settings', exact: true }) - ).toBeVisible() - }) - - await test.step('Set up theme color', async () => { - // Verify we're looking at the project-level settings, - // and it's set to default value - await expect(projectSettingsTab).toBeChecked() - await expect(themeColorSetting).toHaveValue(settingValues.default) - - // Set project-level value to 50 - await themeColorSetting.fill(settingValues.project) - - // Set user-level value to 120 - await userSettingsTab.click() - await themeColorSetting.fill(settingValues.user) - await projectSettingsTab.click() - }) - - await test.step('Reset project settings', async () => { - // Click the reset settings button. - await resetButton('project').click() - - await expect(resetToast('project')).toBeVisible() - await expect(resetToast('project')).not.toBeVisible() - - // Verify it is now set to the inherited user value - await expect(themeColorSetting).toHaveValue(settingValues.user) - - await test.step(`Check that the user settings did not change`, async () => { - await userSettingsTab.click() - await expect(themeColorSetting).toHaveValue(settingValues.user) - }) - - await test.step(`Set project-level again to test the user-level reset`, async () => { - await projectSettingsTab.click() - await themeColorSetting.fill(settingValues.project) - await userSettingsTab.click() - }) - }) - - await test.step('Reset user settings', async () => { - // Click the reset settings button. - await resetButton('user').click() - - await expect(resetToast('user')).toBeVisible() - await expect(resetToast('user')).not.toBeVisible() - - // Verify it is now set to the default value - await expect(themeColorSetting).toHaveValue(settingValues.default) - - await test.step(`Check that the project settings did not change`, async () => { - await projectSettingsTab.click() - await expect(themeColorSetting).toHaveValue(settingValues.project) - }) + test('Project and user settings can be reset', async ({ page, homePage }) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') + const u = await getUtils(page) + await test.step(`Setup`, async () => { + await page.setBodyDimensions({ width: 1200, height: 500 }) + await homePage.goToModelingScene() + await u.waitForPageLoad() + await page.waitForTimeout(1000) + }) + + // Selectors and constants + const projectSettingsTab = page.getByRole('radio', { name: 'Project' }) + const userSettingsTab = page.getByRole('radio', { name: 'User' }) + const resetButton = (level: SettingsLevel) => + page.getByRole('button', { + name: `Reset ${level}-level settings`, }) + const themeColorSetting = page.locator('#themeColor').getByRole('slider') + const settingValues = { + default: '259', + user: '120', + project: '50', } - ) + const resetToast = (level: SettingsLevel) => + page.getByText(`${level}-level settings were reset`) - test.fixme( + await test.step(`Open the settings modal`, async () => { + await page.getByRole('link', { name: 'Settings' }).last().click() + await expect( + page.getByRole('heading', { name: 'Settings', exact: true }) + ).toBeVisible() + }) + + await test.step('Set up theme color', async () => { + // Verify we're looking at the project-level settings, + // and it's set to default value + await expect(projectSettingsTab).toBeChecked() + await expect(themeColorSetting).toHaveValue(settingValues.default) + + // Set project-level value to 50 + await themeColorSetting.fill(settingValues.project) + + // Set user-level value to 120 + await userSettingsTab.click() + await themeColorSetting.fill(settingValues.user) + await projectSettingsTab.click() + }) + + await test.step('Reset project settings', async () => { + // Click the reset settings button. + await resetButton('project').click() + + await expect(resetToast('project')).toBeVisible() + await expect(resetToast('project')).not.toBeVisible() + + // Verify it is now set to the inherited user value + await expect(themeColorSetting).toHaveValue(settingValues.user) + + await test.step(`Check that the user settings did not change`, async () => { + await userSettingsTab.click() + await expect(themeColorSetting).toHaveValue(settingValues.user) + }) + + await test.step(`Set project-level again to test the user-level reset`, async () => { + await projectSettingsTab.click() + await themeColorSetting.fill(settingValues.project) + await userSettingsTab.click() + }) + }) + + await test.step('Reset user settings', async () => { + // Click the reset settings button. + await resetButton('user').click() + + await expect(resetToast('user')).toBeVisible() + await expect(resetToast('user')).not.toBeVisible() + + // Verify it is now set to the default value + await expect(themeColorSetting).toHaveValue(settingValues.default) + + await test.step(`Check that the project settings did not change`, async () => { + await projectSettingsTab.click() + await expect(themeColorSetting).toHaveValue(settingValues.project) + }) + }) + }) + + test( `Project settings override user settings on desktop`, { tag: ['@electron', '@skipWin'] }, async ({ context, page }, testInfo) => { - test.skip( - process.platform === 'win32', - 'TODO: remove this skip https://github.com/KittyCAD/modeling-app/issues/3557' - ) + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') const projectName = 'bracket' const { dir: projectDirName } = await context.folderSetupFn( async (dir) => { @@ -407,12 +398,13 @@ test.describe('Testing settings', () => { ) // It was much easier to test the logo color than the background stream color. - test.fixme( + test( 'user settings reload on external change, on project and modeling view', { tag: '@electron', }, async ({ context, page, tronApp }, testInfo) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') if (!tronApp) { fail() } @@ -466,10 +458,11 @@ test.describe('Testing settings', () => { } ) - test.fixme( + test( 'project settings reload on external change', { tag: '@electron' }, async ({ context, page }, testInfo) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') const { dir: projectDirName } = await context.folderSetupFn( async () => {} ) @@ -982,63 +975,68 @@ fn cube` /** * This test assumes that the default value of the "highlight edges" setting is "on". */ - test.fixme( - `Toggle stream settings multiple times`, - async ({ page, scene, homePage, context, toolbar, cmdBar }, testInfo) => { - await context.folderSetupFn(async (dir) => { - const projectDir = join(dir, 'project-000') - await fsp.mkdir(projectDir, { recursive: true }) - await fsp.copyFile( - executorInputPath('cube.kcl'), - join(projectDir, 'main.kcl') - ) - }) + test(`Toggle stream settings multiple times`, async ({ + page, + scene, + homePage, + context, + toolbar, + cmdBar, + }, testInfo) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') + await context.folderSetupFn(async (dir) => { + const projectDir = join(dir, 'project-000') + await fsp.mkdir(projectDir, { recursive: true }) + await fsp.copyFile( + executorInputPath('cube.kcl'), + join(projectDir, 'main.kcl') + ) + }) - await test.step(`First snapshot`, async () => { - await homePage.openProject('project-000') - await toolbar.closePane('code') - await expect(toolbar.startSketchBtn).toBeEnabled({ timeout: 20_000 }) - await scene.clickNoWhere() - }) + await test.step(`First snapshot`, async () => { + await homePage.openProject('project-000') + await toolbar.closePane('code') + await expect(toolbar.startSketchBtn).toBeEnabled({ timeout: 20_000 }) + await scene.clickNoWhere() + }) - const toast = (value: boolean) => - page.getByText( - `Set highlight edges to "${String(value)}" as a user default` - ) - - await test.step(`Toggle highlightEdges off`, async () => { - await cmdBar.openCmdBar() - await cmdBar.chooseCommand('Settings · modeling · highlight edges') - await cmdBar.selectOption({ name: 'off' }).click() - const falseToast = toast(false) - await expect(falseToast).toBeVisible() - await falseToast.waitFor({ state: 'detached' }) - }) - - await expect(scene.streamWrapper).not.toHaveScreenshot( - 'toggle-settings-initial.png', - { - maxDiffPixels: 15, - mask: [page.getByTestId('model-state-indicator')], - } + const toast = (value: boolean) => + page.getByText( + `Set highlight edges to "${String(value)}" as a user default` ) - await test.step(`Toggle highlightEdges on`, async () => { - await cmdBar.openCmdBar() - await cmdBar.chooseCommand('Settings · modeling · highlight edges') - await cmdBar.selectOption({ name: 'on' }).click() - const trueToast = toast(true) - await expect(trueToast).toBeVisible() - await trueToast.waitFor({ state: 'detached' }) - }) + await test.step(`Toggle highlightEdges off`, async () => { + await cmdBar.openCmdBar() + await cmdBar.chooseCommand('Settings · modeling · highlight edges') + await cmdBar.selectOption({ name: 'off' }).click() + const falseToast = toast(false) + await expect(falseToast).toBeVisible() + await falseToast.waitFor({ state: 'detached' }) + }) - await expect(scene.streamWrapper).toHaveScreenshot( - 'toggle-settings-initial.png', - { - maxDiffPixels: 15, - mask: [page.getByTestId('model-state-indicator')], - } - ) - } - ) + await expect(scene.streamWrapper).not.toHaveScreenshot( + 'toggle-settings-initial.png', + { + maxDiffPixels: 15, + mask: [page.getByTestId('model-state-indicator')], + } + ) + + await test.step(`Toggle highlightEdges on`, async () => { + await cmdBar.openCmdBar() + await cmdBar.chooseCommand('Settings · modeling · highlight edges') + await cmdBar.selectOption({ name: 'on' }).click() + const trueToast = toast(true) + await expect(trueToast).toBeVisible() + await trueToast.waitFor({ state: 'detached' }) + }) + + await expect(scene.streamWrapper).toHaveScreenshot( + 'toggle-settings-initial.png', + { + maxDiffPixels: 15, + mask: [page.getByTestId('model-state-indicator')], + } + ) + }) }) diff --git a/e2e/playwright/text-to-cad-tests.spec.ts b/e2e/playwright/text-to-cad-tests.spec.ts index c1150096d..639921fa8 100644 --- a/e2e/playwright/text-to-cad-tests.spec.ts +++ b/e2e/playwright/text-to-cad-tests.spec.ts @@ -431,10 +431,11 @@ test.describe('Text-to-CAD tests', { tag: ['@skipWin'] }, () => { }) // This will be fine once greg makes prompt at top of file deterministic - test.fixme( + test( 'can do many at once and get many prompts back, and interact with many', { tag: ['@skipWin'] }, async ({ page, homePage }) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') // Let this test run longer since we've seen it timeout. test.setTimeout(180_000) @@ -619,10 +620,11 @@ async function sendPromptFromCommandBar(page: Page, promptStr: string) { }) } -test.fixme( +test( 'Text-to-CAD functionality', { tag: '@electron' }, async ({ context, page }, testInfo) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') const projectName = 'project-000' const prompt = 'lego 2x4' const textToCadFileName = 'lego-2x4.kcl' diff --git a/e2e/playwright/various.spec.ts b/e2e/playwright/various.spec.ts index 512ba0c7a..c7ce7c0f8 100644 --- a/e2e/playwright/various.spec.ts +++ b/e2e/playwright/various.spec.ts @@ -2,7 +2,8 @@ import { test, expect } from './zoo-test' import { doExport, getUtils, makeTemplate } from './test-utils' -test.fixme('Units menu', async ({ page, homePage }) => { +test('Units menu', async ({ page, homePage }) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') await page.setBodyDimensions({ width: 1200, height: 500 }) await homePage.goToModelingScene() @@ -263,186 +264,187 @@ test('First escape in tool pops you out of tool, second exits sketch mode', asyn ).not.toBeVisible() }) -test.fixme( - 'Basic default modeling and sketch hotkeys work', - async ({ page, homePage }) => { - const u = await getUtils(page) +test('Basic default modeling and sketch hotkeys work', async ({ + page, + homePage, +}) => { + test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e') + const u = await getUtils(page) - // This test can run long if it takes a little too long to load - // the engine. - test.setTimeout(90000) - // This test has a weird bug on ubuntu - // Funny, it's flaking on Windows too :). I think there is just something - // actually wrong. - test.skip( - process.platform === 'linux', - 'weird playwright bug on ubuntu https://github.com/KittyCAD/modeling-app/issues/2444' - ) - // Load the app with the code pane open + // This test can run long if it takes a little too long to load + // the engine. + test.setTimeout(90000) + // This test has a weird bug on ubuntu + // Funny, it's flaking on Windows too :). I think there is just something + // actually wrong. + test.skip( + process.platform === 'linux', + 'weird playwright bug on ubuntu https://github.com/KittyCAD/modeling-app/issues/2444' + ) + // Load the app with the code pane open - await test.step(`Set up test`, async () => { - await page.addInitScript(async () => { - localStorage.setItem( - 'store', - JSON.stringify({ - state: { - openPanes: ['code'], - }, - version: 0, - }) - ) - }) - await page.setBodyDimensions({ width: 1200, height: 500 }) - await homePage.goToModelingScene() - await u.openDebugPanel() - await u.expectCmdLog('[data-message-type="execution-done"]') - await u.closeDebugPanel() - }) - - const codePane = page.locator('.cm-content') - const lineButton = page.getByRole('button', { - name: 'line Line', - exact: true, - }) - const arcButton = page.getByRole('button', { - name: 'arc Tangential Arc', - exact: true, - }) - const extrudeButton = page.getByRole('button', { name: 'Extrude' }) - const commandBarComboBox = page.getByPlaceholder('Search commands') - const exitSketchButton = page.getByRole('button', { name: 'Exit Sketch' }) - - await test.step(`Type code with modeling hotkeys, shouldn't fire`, async () => { - await codePane.click() - await page.keyboard.type('//') - await page.keyboard.press('s') - await expect(commandBarComboBox).not.toBeVisible() - await page.keyboard.press('e') - await expect(commandBarComboBox).not.toBeVisible() - await expect(codePane).toHaveText('//se') - }) - - // Blur focus from the code editor, use the s command to sketch - await test.step(`Blur editor focus, enter sketch`, async () => { - /** - * TODO: There is a bug somewhere that causes this test to fail - * if you toggle the codePane closed before your trigger the - * start of the sketch. - * and a separate Safari-only bug that causes the test to fail - * if the pane is open the entire test. The maintainer of CodeMirror - * has pinpointed this to the unusual browser behavior: - * https://discuss.codemirror.net/t/how-to-force-unfocus-of-the-codemirror-element-in-safari/8095/3 - */ - await blurCodeEditor() - await page.waitForTimeout(1000) - await page.keyboard.press('s') - await page.waitForTimeout(1000) - await page.mouse.move(800, 300, { steps: 5 }) - await page.mouse.click(800, 300) - await page.waitForTimeout(1000) - await expect(lineButton).toHaveAttribute('aria-pressed', 'true', { - timeout: 15_000, - }) - }) - - // Use some sketch hotkeys to create a sketch (l and a for now) - await test.step(`Incomplete sketch with hotkeys`, async () => { - await test.step(`Draw a line`, async () => { - await page.mouse.move(700, 200, { steps: 5 }) - await page.mouse.click(700, 200) - await page.mouse.move(800, 250, { steps: 5 }) - await page.mouse.click(800, 250) - }) - - await test.step(`Unequip line tool`, async () => { - await page.keyboard.press('l') - await expect(lineButton).not.toHaveAttribute('aria-pressed', 'true') - }) - - await test.step(`Draw a tangential arc`, async () => { - await page.keyboard.press('a') - await expect(arcButton).toHaveAttribute('aria-pressed', 'true', { - timeout: 10_000, + await test.step(`Set up test`, async () => { + await page.addInitScript(async () => { + localStorage.setItem( + 'store', + JSON.stringify({ + state: { + openPanes: ['code'], + }, + version: 0, }) - await page.mouse.move(1000, 100, { steps: 5 }) - await page.mouse.click(1000, 100) - }) - - await test.step(`Unequip with escape, equip line tool`, async () => { - await page.keyboard.press('Escape') - await page.keyboard.press('l') - await page.waitForTimeout(50) - await expect(lineButton).toHaveAttribute('aria-pressed', 'true') - }) + ) }) + await page.setBodyDimensions({ width: 1200, height: 500 }) + await homePage.goToModelingScene() + await u.openDebugPanel() + await u.expectCmdLog('[data-message-type="execution-done"]') + await u.closeDebugPanel() + }) - await test.step(`Type code with sketch hotkeys, shouldn't fire`, async () => { - // Since there's code now, we have to get to the end of the line - await page.locator('.cm-line').last().click() - await page.keyboard.down('ControlOrMeta') - await page.keyboard.press('ArrowRight') - await page.keyboard.up('ControlOrMeta') + const codePane = page.locator('.cm-content') + const lineButton = page.getByRole('button', { + name: 'line Line', + exact: true, + }) + const arcButton = page.getByRole('button', { + name: 'arc Tangential Arc', + exact: true, + }) + const extrudeButton = page.getByRole('button', { name: 'Extrude' }) + const commandBarComboBox = page.getByPlaceholder('Search commands') + const exitSketchButton = page.getByRole('button', { name: 'Exit Sketch' }) - await page.keyboard.press('Enter') - await page.keyboard.type('//') - await page.keyboard.press('l') - await expect(lineButton).toHaveAttribute('aria-pressed', 'true') - await page.keyboard.press('a') - await expect(lineButton).toHaveAttribute('aria-pressed', 'true') - await expect(codePane).toContainText('//la') - await page.keyboard.press('Backspace') - await page.keyboard.press('Backspace') - await page.keyboard.press('Backspace') - await page.keyboard.press('Backspace') + await test.step(`Type code with modeling hotkeys, shouldn't fire`, async () => { + await codePane.click() + await page.keyboard.type('//') + await page.keyboard.press('s') + await expect(commandBarComboBox).not.toBeVisible() + await page.keyboard.press('e') + await expect(commandBarComboBox).not.toBeVisible() + await expect(codePane).toHaveText('//se') + }) + + // Blur focus from the code editor, use the s command to sketch + await test.step(`Blur editor focus, enter sketch`, async () => { + /** + * TODO: There is a bug somewhere that causes this test to fail + * if you toggle the codePane closed before your trigger the + * start of the sketch. + * and a separate Safari-only bug that causes the test to fail + * if the pane is open the entire test. The maintainer of CodeMirror + * has pinpointed this to the unusual browser behavior: + * https://discuss.codemirror.net/t/how-to-force-unfocus-of-the-codemirror-element-in-safari/8095/3 + */ + await blurCodeEditor() + await page.waitForTimeout(1000) + await page.keyboard.press('s') + await page.waitForTimeout(1000) + await page.mouse.move(800, 300, { steps: 5 }) + await page.mouse.click(800, 300) + await page.waitForTimeout(1000) + await expect(lineButton).toHaveAttribute('aria-pressed', 'true', { + timeout: 15_000, }) + }) - await test.step(`Close profile and exit sketch`, async () => { - await blurCodeEditor() + // Use some sketch hotkeys to create a sketch (l and a for now) + await test.step(`Incomplete sketch with hotkeys`, async () => { + await test.step(`Draw a line`, async () => { await page.mouse.move(700, 200, { steps: 5 }) await page.mouse.click(700, 200) - // On close it will unequip the line tool. - await expect(lineButton).toHaveAttribute('aria-pressed', 'false') - await expect(exitSketchButton).toBeEnabled() - await page.keyboard.press('Escape') - await expect( - page.getByRole('button', { name: 'Exit Sketch' }) - ).not.toBeVisible() + await page.mouse.move(800, 250, { steps: 5 }) + await page.mouse.click(800, 250) }) - // Extrude with e - await test.step(`Extrude the sketch`, async () => { - await page.mouse.click(750, 150) - await blurCodeEditor() - await expect(extrudeButton).toBeEnabled() - await page.keyboard.press('e') - await page.waitForTimeout(500) - await page.mouse.move(800, 200, { steps: 5 }) - await page.mouse.click(800, 200) - await expect(page.getByRole('button', { name: 'Continue' })).toBeVisible({ - timeout: 20_000, + await test.step(`Unequip line tool`, async () => { + await page.keyboard.press('l') + await expect(lineButton).not.toHaveAttribute('aria-pressed', 'true') + }) + + await test.step(`Draw a tangential arc`, async () => { + await page.keyboard.press('a') + await expect(arcButton).toHaveAttribute('aria-pressed', 'true', { + timeout: 10_000, }) - await page.getByRole('button', { name: 'Continue' }).click() - await expect( - page.getByRole('button', { name: 'Submit command' }) - ).toBeVisible() - await page.getByRole('button', { name: 'Submit command' }).click() - await expect(page.locator('.cm-content')).toContainText('extrude(') + await page.mouse.move(1000, 100, { steps: 5 }) + await page.mouse.click(1000, 100) }) - // await codePaneButton.click() - // await expect(u.codeLocator).not.toBeVisible() - - /** - * work-around: to stop `keyboard.press()` from typing in the editor even when it should be blurred - */ - async function blurCodeEditor() { - await page.getByRole('button', { name: 'Commands' }).click() - await page.waitForTimeout(100) + await test.step(`Unequip with escape, equip line tool`, async () => { await page.keyboard.press('Escape') - await page.waitForTimeout(100) - } + await page.keyboard.press('l') + await page.waitForTimeout(50) + await expect(lineButton).toHaveAttribute('aria-pressed', 'true') + }) + }) + + await test.step(`Type code with sketch hotkeys, shouldn't fire`, async () => { + // Since there's code now, we have to get to the end of the line + await page.locator('.cm-line').last().click() + await page.keyboard.down('ControlOrMeta') + await page.keyboard.press('ArrowRight') + await page.keyboard.up('ControlOrMeta') + + await page.keyboard.press('Enter') + await page.keyboard.type('//') + await page.keyboard.press('l') + await expect(lineButton).toHaveAttribute('aria-pressed', 'true') + await page.keyboard.press('a') + await expect(lineButton).toHaveAttribute('aria-pressed', 'true') + await expect(codePane).toContainText('//la') + await page.keyboard.press('Backspace') + await page.keyboard.press('Backspace') + await page.keyboard.press('Backspace') + await page.keyboard.press('Backspace') + }) + + await test.step(`Close profile and exit sketch`, async () => { + await blurCodeEditor() + await page.mouse.move(700, 200, { steps: 5 }) + await page.mouse.click(700, 200) + // On close it will unequip the line tool. + await expect(lineButton).toHaveAttribute('aria-pressed', 'false') + await expect(exitSketchButton).toBeEnabled() + await page.keyboard.press('Escape') + await expect( + page.getByRole('button', { name: 'Exit Sketch' }) + ).not.toBeVisible() + }) + + // Extrude with e + await test.step(`Extrude the sketch`, async () => { + await page.mouse.click(750, 150) + await blurCodeEditor() + await expect(extrudeButton).toBeEnabled() + await page.keyboard.press('e') + await page.waitForTimeout(500) + await page.mouse.move(800, 200, { steps: 5 }) + await page.mouse.click(800, 200) + await expect(page.getByRole('button', { name: 'Continue' })).toBeVisible({ + timeout: 20_000, + }) + await page.getByRole('button', { name: 'Continue' }).click() + await expect( + page.getByRole('button', { name: 'Submit command' }) + ).toBeVisible() + await page.getByRole('button', { name: 'Submit command' }).click() + await expect(page.locator('.cm-content')).toContainText('extrude(') + }) + + // await codePaneButton.click() + // await expect(u.codeLocator).not.toBeVisible() + + /** + * work-around: to stop `keyboard.press()` from typing in the editor even when it should be blurred + */ + async function blurCodeEditor() { + await page.getByRole('button', { name: 'Commands' }).click() + await page.waitForTimeout(100) + await page.keyboard.press('Escape') + await page.waitForTimeout(100) } -) +}) test('Delete key does not navigate back', async ({ page, homePage }) => { await page.setBodyDimensions({ width: 1200, height: 500 })