Continue running broken tests for Axiom metrics (#5883)
* Install Vector on Ubuntu to log failed test to Axiom * Allow flaky tests to run on main for Axiom metrics * Enable problematic tests on a dedicated branch
This commit is contained in:
38
.github/ci-cd-scripts/playwright-electron.sh
vendored
38
.github/ci-cd-scripts/playwright-electron.sh
vendored
@ -4,27 +4,27 @@
|
|||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
if [[ ! -f "test-results/.last-run.json" ]]; then
|
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"
|
echo "run playwright normally"
|
||||||
if [[ "$3" == *ubuntu* ]]; then
|
if [[ "$3" == *ubuntu* ]]; then
|
||||||
xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- yarn test:playwright:electron:ubuntu -- --shard=$1/$2 || true
|
xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- yarn test:playwright:electron:ubuntu -- --shard=$1/$2 || true
|
||||||
elif [[ "$3" == *windows* ]]; then
|
elif [[ "$3" == *windows* ]]; then
|
||||||
yarn test:playwright:electron:windows -- --shard=$1/$2 || true
|
yarn test:playwright:electron:windows -- --shard=$1/$2 || true
|
||||||
elif [[ "$3" == *macos* ]]; then
|
elif [[ "$3" == *macos* ]]; then
|
||||||
yarn test:playwright:electron:macos -- --shard=$1/$2 || true
|
yarn test:playwright:electron:macos -- --shard=$1/$2 || true
|
||||||
else
|
else
|
||||||
echo "Do not run playwright. Unable to detect os runtime."
|
echo "Do not run Playwright. Unable to detect os runtime."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
# # send to axiom
|
# Log failures for Axiom to pick up
|
||||||
node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1
|
node playwrightProcess.mjs > /tmp/github-actions.log
|
||||||
fi
|
fi
|
||||||
|
|
||||||
retry=1
|
retry=1
|
||||||
max_retrys=1
|
max_retries=1
|
||||||
|
|
||||||
# retry failed tests, doing our own retries because using inbuilt playwright retries causes connection issues
|
# Retry failed tests, doing our own retries because using inbuilt Playwright retries causes connection issues
|
||||||
while [[ $retry -le $max_retrys ]]; do
|
while [[ $retry -le $max_retries ]]; do
|
||||||
if [[ -f "test-results/.last-run.json" ]]; then
|
if [[ -f "test-results/.last-run.json" ]]; then
|
||||||
failed_tests=$(jq '.failedTests | length' test-results/.last-run.json)
|
failed_tests=$(jq '.failedTests | length' test-results/.last-run.json)
|
||||||
if [[ $failed_tests -gt 0 ]]; then
|
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."
|
echo "Do not run playwright. Unable to detect os runtime."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
# send to axiom
|
# Log failures for Axiom to pick up
|
||||||
node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1
|
node playwrightProcess.mjs > /tmp/github-actions.log
|
||||||
retry=$((retry + 1))
|
retry=$((retry + 1))
|
||||||
else
|
else
|
||||||
echo "retried=false" >>$GITHUB_OUTPUT
|
echo "retried=false" >>$GITHUB_OUTPUT
|
||||||
@ -58,7 +58,7 @@ echo "retried=false" >>$GITHUB_OUTPUT
|
|||||||
if [[ -f "test-results/.last-run.json" ]]; then
|
if [[ -f "test-results/.last-run.json" ]]; then
|
||||||
failed_tests=$(jq '.failedTests | length' test-results/.last-run.json)
|
failed_tests=$(jq '.failedTests | length' test-results/.last-run.json)
|
||||||
if [[ $failed_tests -gt 0 ]]; then
|
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
|
exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
20
.github/workflows/e2e-tests.yml
vendored
20
.github/workflows/e2e-tests.yml
vendored
@ -340,14 +340,22 @@ jobs:
|
|||||||
if: needs.conditions.outputs.should-run == 'true'
|
if: needs.conditions.outputs.should-run == 'true'
|
||||||
run: yarn tronb:vite:dev
|
run: yarn tronb:vite:dev
|
||||||
|
|
||||||
- name: Install good sed
|
- name: Install vector
|
||||||
if: startsWith(matrix.os, 'macos')
|
if: contains(matrix.os, 'ubuntu')
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
brew install gnu-sed
|
curl --proto '=https' --tlsv1.2 -sSfL https://sh.vector.dev > /tmp/vector.sh
|
||||||
echo "/opt/homebrew/opt/gnu-sed/libexec/gnubin" >> $GITHUB_PATH
|
chmod +x /tmp/vector.sh
|
||||||
|
/tmp/vector.sh -y -no-modify-path
|
||||||
# TODO: Add back axiom logs
|
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
|
- uses: actions/download-artifact@v4
|
||||||
if: ${{ needs.conditions.outputs.should-run == 'true' && !cancelled() && (success() || failure()) }}
|
if: ${{ needs.conditions.outputs.should-run == 'true' && !cancelled() && (success() || failure()) }}
|
||||||
|
@ -153,7 +153,8 @@ async function doBasicSketch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
test.describe('Basic sketch', { tag: ['@skipWin'] }, () => {
|
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'])
|
await doBasicSketch(page, homePage, ['code'])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -46,11 +46,12 @@ test.describe('Code pane and errors', { tag: ['@skipWin'] }, () => {
|
|||||||
await expect(codePaneButtonHolder).toContainText('notification')
|
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,
|
page,
|
||||||
homePage,
|
homePage,
|
||||||
editor,
|
editor,
|
||||||
}) => {
|
}) => {
|
||||||
|
test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e')
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
|
|
||||||
// Load the app with the working starter code
|
// 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()
|
await expect(page.locator('.cm-tooltip').first()).toBeVisible()
|
||||||
})
|
})
|
||||||
|
|
||||||
test.fixme(
|
test('When error is not in view you can click the badge to scroll to it', async ({
|
||||||
'When error is not in view you can click the badge to scroll to it',
|
page,
|
||||||
async ({ page, homePage, context }) => {
|
homePage,
|
||||||
// Load the app with the working starter code
|
context,
|
||||||
await context.addInitScript((code) => {
|
}) => {
|
||||||
localStorage.setItem('persistCode', code)
|
test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e')
|
||||||
}, TEST_CODE_LONG_WITH_ERROR_OUT_OF_VIEW)
|
// 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 page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
await page.waitForTimeout(1000)
|
await page.waitForTimeout(1000)
|
||||||
|
|
||||||
// Ensure badge is present
|
// Ensure badge is present
|
||||||
const codePaneButtonHolder = page.locator('#code-button-holder')
|
const codePaneButtonHolder = page.locator('#code-button-holder')
|
||||||
await expect(codePaneButtonHolder).toContainText('notification')
|
await expect(codePaneButtonHolder).toContainText('notification')
|
||||||
|
|
||||||
// Ensure we have no errors in the gutter, since error out of view.
|
// Ensure we have no errors in the gutter, since error out of view.
|
||||||
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
||||||
|
|
||||||
// Click the badge.
|
// Click the badge.
|
||||||
const badge = page.locator('#code-badge')
|
const badge = page.locator('#code-badge')
|
||||||
await expect(badge).toBeVisible()
|
await expect(badge).toBeVisible()
|
||||||
await badge.click()
|
await badge.click()
|
||||||
|
|
||||||
// Ensure we have an error diagnostic.
|
// Ensure we have an error diagnostic.
|
||||||
await expect(page.locator('.cm-lint-marker-error').first()).toBeVisible()
|
await expect(page.locator('.cm-lint-marker-error').first()).toBeVisible()
|
||||||
|
|
||||||
// Hover over the error to see the error message
|
// Hover over the error to see the error message
|
||||||
await page.hover('.cm-lint-marker-error')
|
await page.hover('.cm-lint-marker-error')
|
||||||
await expect(
|
await expect(
|
||||||
page
|
page
|
||||||
.getByText(
|
.getByText(
|
||||||
'Modeling command failed: [ApiError { error_code: InternalEngine, message: "Solid3D revolve failed: sketch profile must lie entirely on one side of the revolution axis" }]'
|
'Modeling command failed: [ApiError { error_code: InternalEngine, message: "Solid3D revolve failed: sketch profile must lie entirely on one side of the revolution axis" }]'
|
||||||
)
|
)
|
||||||
.first()
|
.first()
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
}
|
})
|
||||||
)
|
|
||||||
|
|
||||||
test('When error is not in view WITH LINTS you can click the badge to scroll to it', async ({
|
test('When error is not in view WITH LINTS you can click the badge to scroll to it', async ({
|
||||||
context,
|
context,
|
||||||
|
@ -47,7 +47,8 @@ test.describe('Command bar tests', { tag: ['@skipWin'] }, () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// TODO: fix this test after the electron migration
|
// 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 () => {
|
await page.addInitScript(async () => {
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
'persistCode',
|
'persistCode',
|
||||||
|
@ -635,14 +635,16 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
|
|||||||
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
||||||
})
|
})
|
||||||
|
|
||||||
test.fixme(
|
test('error with 2 source ranges gets 2 diagnostics', async ({
|
||||||
'error with 2 source ranges gets 2 diagnostics',
|
page,
|
||||||
async ({ page, homePage }) => {
|
homePage,
|
||||||
const u = await getUtils(page)
|
}) => {
|
||||||
await page.addInitScript(async () => {
|
test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e')
|
||||||
localStorage.setItem(
|
const u = await getUtils(page)
|
||||||
'persistCode',
|
await page.addInitScript(async () => {
|
||||||
`length = .750
|
localStorage.setItem(
|
||||||
|
'persistCode',
|
||||||
|
`length = .750
|
||||||
width = 0.500
|
width = 0.500
|
||||||
height = 0.500
|
height = 0.500
|
||||||
dia = 4
|
dia = 4
|
||||||
@ -657,53 +659,52 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
|
|||||||
return squareHoleSketch
|
return squareHoleSketch
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await u.waitForPageLoad()
|
await u.waitForPageLoad()
|
||||||
await page.waitForTimeout(1000)
|
await page.waitForTimeout(1000)
|
||||||
|
|
||||||
await u.openDebugPanel()
|
await u.openDebugPanel()
|
||||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||||
await u.closeDebugPanel()
|
await u.closeDebugPanel()
|
||||||
|
|
||||||
// check no error to begin with
|
// check no error to begin with
|
||||||
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
||||||
|
|
||||||
// Click on the bottom of the code editor to add a new line
|
// Click on the bottom of the code editor to add a new line
|
||||||
await u.codeLocator.click()
|
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('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.press('Enter')
|
||||||
await page.keyboard.type(`extrusion = startSketchOn('XY')
|
await page.keyboard.type(`extrusion = startSketchOn('XY')
|
||||||
|> circle(center: [0, 0], radius: dia/2)
|
|> circle(center: [0, 0], radius: dia/2)
|
||||||
|> hole(squareHole(length, width, height), %)
|
|> hole(squareHole(length, width, height), %)
|
||||||
|> extrude(length = height)`)
|
|> extrude(length = height)`)
|
||||||
|
|
||||||
// error in gutter
|
// error in gutter
|
||||||
await expect(page.locator('.cm-lint-marker-error').first()).toBeVisible()
|
await expect(page.locator('.cm-lint-marker-error').first()).toBeVisible()
|
||||||
await page.hover('.cm-lint-marker-error:first-child')
|
await page.hover('.cm-lint-marker-error:first-child')
|
||||||
await expect(
|
await expect(
|
||||||
page.getByText('Expected 2 arguments, got 3').first()
|
page.getByText('Expected 2 arguments, got 3').first()
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
|
|
||||||
// Make sure there are two diagnostics
|
// Make sure there are two diagnostics
|
||||||
await expect(page.locator('.cm-lint-marker-error')).toHaveCount(2)
|
await expect(page.locator('.cm-lint-marker-error')).toHaveCount(2)
|
||||||
}
|
})
|
||||||
)
|
|
||||||
test('if your kcl gets an error from the engine it is inlined', async ({
|
test('if your kcl gets an error from the engine it is inlined', async ({
|
||||||
context,
|
context,
|
||||||
page,
|
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`,
|
`Can use the import stdlib function on a local OBJ file`,
|
||||||
{ tag: '@electron' },
|
{ tag: '@electron' },
|
||||||
async ({ page, context }, testInfo) => {
|
async ({ page, context }, testInfo) => {
|
||||||
|
test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e')
|
||||||
await context.folderSetupFn(async (dir) => {
|
await context.folderSetupFn(async (dir) => {
|
||||||
const bracketDir = join(dir, 'cube')
|
const bracketDir = join(dir, 'cube')
|
||||||
await fsp.mkdir(bracketDir, { recursive: true })
|
await fsp.mkdir(bracketDir, { recursive: true })
|
||||||
|
@ -266,12 +266,13 @@ test.describe('when using the file tree to', () => {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
test.fixme(
|
test(
|
||||||
'loading small file, then large, then back to small',
|
'loading small file, then large, then back to small',
|
||||||
{
|
{
|
||||||
tag: '@electron',
|
tag: '@electron',
|
||||||
},
|
},
|
||||||
async ({ page }, testInfo) => {
|
async ({ page }, testInfo) => {
|
||||||
|
test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e')
|
||||||
const {
|
const {
|
||||||
panesOpen,
|
panesOpen,
|
||||||
pasteCodeInEditor,
|
pasteCodeInEditor,
|
||||||
|
@ -319,237 +319,240 @@ test.describe('Onboarding tests', () => {
|
|||||||
// (lee) The two avatar tests are weird because even on main, we don't have
|
// (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
|
// 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.
|
// low impact of an avatar not showing I'm changing this to fixme.
|
||||||
test.fixme(
|
test('Avatar text updates depending on image load success', async ({
|
||||||
'Avatar text updates depending on image load success',
|
context,
|
||||||
async ({ context, page, homePage, tronApp }) => {
|
page,
|
||||||
if (!tronApp) {
|
homePage,
|
||||||
fail()
|
tronApp,
|
||||||
}
|
}) => {
|
||||||
|
test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e')
|
||||||
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 }) => {
|
|
||||||
if (!tronApp) {
|
if (!tronApp) {
|
||||||
fail()
|
fail()
|
||||||
}
|
}
|
||||||
|
|
||||||
await tronApp.cleanProjectDir({
|
await tronApp.cleanProjectDir({
|
||||||
app: {
|
app: {
|
||||||
onboarding_status: 'dismissed',
|
onboarding_status: '',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
await context.folderSetupFn(async (dir) => {
|
// Override beforeEach test setup
|
||||||
const routerTemplateDir = join(dir, 'router-template-slate')
|
await context.addInitScript(
|
||||||
await fsp.mkdir(routerTemplateDir, { recursive: true })
|
async ({ settingsKey, settings }) => {
|
||||||
await fsp.copyFile(
|
localStorage.setItem(settingsKey, settings)
|
||||||
executorInputPath('router-template-slate.kcl'),
|
},
|
||||||
join(routerTemplateDir, 'main.kcl')
|
{
|
||||||
)
|
settingsKey: TEST_SETTINGS_KEY,
|
||||||
})
|
settings: settingsToToml({
|
||||||
|
settings: TEST_SETTINGS_ONBOARDING_USER_MENU,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// Our constants
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
const u = await getUtils(page)
|
await homePage.goToModelingScene()
|
||||||
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
|
// Test that the text in this step is correct
|
||||||
.getByTestId('project-sidebar-toggle')
|
const avatarLocator = page.getByTestId('user-sidebar-toggle').locator('img')
|
||||||
.filter({ hasText: 'Tutorial Project 00' })
|
const onboardingOverlayLocator = page
|
||||||
const tutorialModalText = page.getByText('Welcome to Modeling App!')
|
.getByTestId('onboarding-content')
|
||||||
const tutorialDismissButton = page.getByRole('button', { name: 'Dismiss' })
|
.locator('div')
|
||||||
const userMenuButton = page.getByTestId('user-sidebar-toggle')
|
.nth(1)
|
||||||
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 () => {
|
// Expect the avatar to be visible and for the text to reference it
|
||||||
await expect(
|
await expect(avatarLocator).toBeVisible()
|
||||||
page.getByRole('heading', { name: 'Your Projects' })
|
await expect(onboardingOverlayLocator).toBeVisible()
|
||||||
).toBeVisible()
|
await expect(onboardingOverlayLocator).toContainText('your avatar')
|
||||||
await expect(projectCard).toBeVisible()
|
|
||||||
await projectCard.click()
|
|
||||||
await u.waitForPageLoad()
|
|
||||||
})
|
|
||||||
|
|
||||||
await test.step('Restart the onboarding from help menu', async () => {
|
// This is to force the avatar to 404.
|
||||||
await helpMenuButton.click()
|
// For our test image (only triggers locally. on CI, it's Kurt's /
|
||||||
await restartOnboardingButton.click()
|
// gravatar image )
|
||||||
|
await page.route('/cat.jpg', async (route) => {
|
||||||
await nextButton.hover()
|
await route.fulfill({
|
||||||
await nextButton.click()
|
status: 404,
|
||||||
})
|
contentType: 'text/plain',
|
||||||
|
body: 'Not Found!',
|
||||||
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()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 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()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
@ -850,157 +850,160 @@ openSketch = startSketchOn('XY')
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test.fixme(
|
test(`Shift-click to select and deselect sketch segments`, async ({
|
||||||
`Shift-click to select and deselect sketch segments`,
|
page,
|
||||||
async ({ page, homePage, scene, editor }) => {
|
homePage,
|
||||||
// Locators
|
scene,
|
||||||
const firstPointLocation = { x: 200, y: 100 }
|
editor,
|
||||||
const secondPointLocation = { x: 800, y: 100 }
|
}) => {
|
||||||
const thirdPointLocation = { x: 800, y: 400 }
|
test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e')
|
||||||
const fristSegmentLocation = { x: 750, y: 100 }
|
// Locators
|
||||||
const secondSegmentLocation = { x: 800, y: 150 }
|
const firstPointLocation = { x: 200, y: 100 }
|
||||||
const planeLocation = { x: 700, y: 200 }
|
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
|
// Click helpers
|
||||||
const [clickFirstPoint] = scene.makeMouseHelpers(
|
const [clickFirstPoint] = scene.makeMouseHelpers(
|
||||||
firstPointLocation.x,
|
firstPointLocation.x,
|
||||||
firstPointLocation.y
|
firstPointLocation.y
|
||||||
)
|
)
|
||||||
const [clickSecondPoint] = scene.makeMouseHelpers(
|
const [clickSecondPoint] = scene.makeMouseHelpers(
|
||||||
secondPointLocation.x,
|
secondPointLocation.x,
|
||||||
secondPointLocation.y
|
secondPointLocation.y
|
||||||
)
|
)
|
||||||
const [clickThirdPoint] = scene.makeMouseHelpers(
|
const [clickThirdPoint] = scene.makeMouseHelpers(
|
||||||
thirdPointLocation.x,
|
thirdPointLocation.x,
|
||||||
thirdPointLocation.y
|
thirdPointLocation.y
|
||||||
)
|
)
|
||||||
const [clickFirstSegment] = scene.makeMouseHelpers(
|
const [clickFirstSegment] = scene.makeMouseHelpers(
|
||||||
fristSegmentLocation.x,
|
fristSegmentLocation.x,
|
||||||
fristSegmentLocation.y
|
fristSegmentLocation.y
|
||||||
)
|
)
|
||||||
const [clickSecondSegment] = scene.makeMouseHelpers(
|
const [clickSecondSegment] = scene.makeMouseHelpers(
|
||||||
secondSegmentLocation.x,
|
secondSegmentLocation.x,
|
||||||
secondSegmentLocation.y
|
secondSegmentLocation.y
|
||||||
)
|
)
|
||||||
const [clickPlane] = scene.makeMouseHelpers(
|
const [clickPlane] = scene.makeMouseHelpers(
|
||||||
planeLocation.x,
|
planeLocation.x,
|
||||||
planeLocation.y
|
planeLocation.y
|
||||||
)
|
)
|
||||||
|
|
||||||
// Colors
|
// Colors
|
||||||
const edgeColorWhite: [number, number, number] = [220, 220, 220]
|
const edgeColorWhite: [number, number, number] = [220, 220, 220]
|
||||||
const edgeColorBlue: [number, number, number] = [20, 20, 200]
|
const edgeColorBlue: [number, number, number] = [20, 20, 200]
|
||||||
const backgroundColor: [number, number, number] = [30, 30, 30]
|
const backgroundColor: [number, number, number] = [30, 30, 30]
|
||||||
const tolerance = 40
|
const tolerance = 40
|
||||||
const timeout = 150
|
const timeout = 150
|
||||||
|
|
||||||
// Setup
|
// Setup
|
||||||
await test.step(`Initial test setup`, async () => {
|
await test.step(`Initial test setup`, async () => {
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
await homePage.goToModelingScene()
|
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(
|
await scene.expectPixelColor(
|
||||||
backgroundColor,
|
edgeColorBlue,
|
||||||
secondPointLocation,
|
fristSegmentLocation,
|
||||||
|
tolerance
|
||||||
|
)
|
||||||
|
await scene.expectPixelColor(
|
||||||
|
edgeColorWhite,
|
||||||
|
secondSegmentLocation,
|
||||||
tolerance
|
tolerance
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
await test.step('Select the second segment (Shift-click)', async () => {
|
||||||
await test.step('Select and deselect a single sketch segment', async () => {
|
await page.keyboard.down('Shift')
|
||||||
await test.step('Get into sketch mode', async () => {
|
await page.waitForTimeout(timeout)
|
||||||
await editor.closePane()
|
await clickSecondSegment()
|
||||||
await page.waitForTimeout(timeout)
|
await page.waitForTimeout(timeout)
|
||||||
await page.getByRole('button', { name: 'Start Sketch' }).click()
|
await page.keyboard.up('Shift')
|
||||||
await page.waitForTimeout(timeout)
|
await scene.expectPixelColor(
|
||||||
await clickPlane()
|
edgeColorBlue,
|
||||||
await page.waitForTimeout(1000)
|
fristSegmentLocation,
|
||||||
})
|
tolerance
|
||||||
await test.step('Draw sketch', async () => {
|
)
|
||||||
await clickFirstPoint()
|
await scene.expectPixelColor(
|
||||||
await page.waitForTimeout(timeout)
|
edgeColorBlue,
|
||||||
await clickSecondPoint()
|
secondSegmentLocation,
|
||||||
await page.waitForTimeout(timeout)
|
tolerance
|
||||||
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('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 ({
|
test(`Offset plane point-and-click`, async ({
|
||||||
context,
|
context,
|
||||||
|
@ -1244,10 +1244,11 @@ test(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
test.fixme(
|
test(
|
||||||
'Deleting projects, can delete individual project, can still create projects after deleting all',
|
'Deleting projects, can delete individual project, can still create projects after deleting all',
|
||||||
{ tag: '@electron' },
|
{ tag: '@electron' },
|
||||||
async ({ context, page }, testInfo) => {
|
async ({ context, page }, testInfo) => {
|
||||||
|
test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e')
|
||||||
const projectData = [
|
const projectData = [
|
||||||
['router-template-slate', 'cylinder.kcl'],
|
['router-template-slate', 'cylinder.kcl'],
|
||||||
['bracket', 'focusrite_scarlett_mounting_braket.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.',
|
'When the project folder is empty, user can create new project and open it.',
|
||||||
{ tag: '@electron' },
|
{ tag: '@electron' },
|
||||||
async ({ page }, testInfo) => {
|
async ({ page }, testInfo) => {
|
||||||
|
test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e')
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
@ -2050,10 +2052,11 @@ test(
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Flaky
|
// Flaky
|
||||||
test.fixme(
|
test(
|
||||||
'Original project name persist after onboarding',
|
'Original project name persist after onboarding',
|
||||||
{ tag: '@electron' },
|
{ tag: '@electron' },
|
||||||
async ({ page }, testInfo) => {
|
async ({ page }, testInfo) => {
|
||||||
|
test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e')
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
const getAllProjects = () => page.getByTestId('project-link').all()
|
const getAllProjects = () => page.getByTestId('project-link').all()
|
||||||
|
@ -196,60 +196,65 @@ test.describe('Prompt-to-edit tests', { tag: '@skipWin' }, () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test.fixme(
|
test(`manual code selection rename`, async ({
|
||||||
`manual code selection rename`,
|
context,
|
||||||
async ({ context, homePage, cmdBar, editor, page, scene }) => {
|
homePage,
|
||||||
const body1CapCoords = { x: 571, y: 311 }
|
cmdBar,
|
||||||
|
editor,
|
||||||
|
page,
|
||||||
|
scene,
|
||||||
|
}) => {
|
||||||
|
test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e')
|
||||||
|
const body1CapCoords = { x: 571, y: 311 }
|
||||||
|
|
||||||
await context.addInitScript((file) => {
|
await context.addInitScript((file) => {
|
||||||
localStorage.setItem('persistCode', file)
|
localStorage.setItem('persistCode', file)
|
||||||
}, file)
|
}, file)
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.waitForExecutionDone()
|
||||||
|
|
||||||
const submittingToast = page.getByText('Submitting to Text-to-CAD API...')
|
const submittingToast = page.getByText('Submitting to Text-to-CAD API...')
|
||||||
const successToast = page.getByText('Prompt to edit successful')
|
const successToast = page.getByText('Prompt to edit successful')
|
||||||
const acceptBtn = page.getByRole('button', { name: 'checkmark Accept' })
|
const acceptBtn = page.getByRole('button', { name: 'checkmark Accept' })
|
||||||
|
|
||||||
await test.step('wait for scene to load and select code in editor', async () => {
|
await test.step('wait for scene to load and select code in editor', async () => {
|
||||||
// Find and select the text "sketch002" in the editor
|
// Find and select the text "sketch002" in the editor
|
||||||
await editor.selectText('sketch002')
|
await editor.selectText('sketch002')
|
||||||
|
|
||||||
// Verify the selection was made
|
// Verify the selection was made
|
||||||
await editor.expectState({
|
await editor.expectState({
|
||||||
highlightedCode: '',
|
highlightedCode: '',
|
||||||
activeLines: ["sketch002 = startSketchOn('XZ')"],
|
activeLines: ["sketch002 = startSketchOn('XZ')"],
|
||||||
diagnostics: [],
|
diagnostics: [],
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
|
||||||
await test.step('fire off edit prompt', async () => {
|
await test.step('fire off edit prompt', async () => {
|
||||||
await scene.expectPixelColor([134, 134, 134], body1CapCoords, 15)
|
await scene.expectPixelColor([134, 134, 134], body1CapCoords, 15)
|
||||||
await cmdBar.openCmdBar('promptToEdit')
|
await cmdBar.openCmdBar('promptToEdit')
|
||||||
await page
|
await page
|
||||||
.getByTestId('cmd-bar-arg-value')
|
.getByTestId('cmd-bar-arg-value')
|
||||||
.fill('Please rename to mySketch001')
|
.fill('Please rename to mySketch001')
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await expect(submittingToast).toBeVisible()
|
await expect(submittingToast).toBeVisible()
|
||||||
await expect(submittingToast).not.toBeVisible({
|
await expect(submittingToast).not.toBeVisible({
|
||||||
timeout: 2 * 60_000,
|
timeout: 2 * 60_000,
|
||||||
})
|
|
||||||
await expect(successToast).toBeVisible()
|
|
||||||
})
|
})
|
||||||
|
await expect(successToast).toBeVisible()
|
||||||
|
})
|
||||||
|
|
||||||
await test.step('verify rename change and accept it', async () => {
|
await test.step('verify rename change and accept it', async () => {
|
||||||
await editor.expectEditor.toContain('mySketch001 = startSketchOn')
|
await editor.expectEditor.toContain('mySketch001 = startSketchOn')
|
||||||
await editor.expectEditor.not.toContain('sketch002 = startSketchOn')
|
await editor.expectEditor.not.toContain('sketch002 = startSketchOn')
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
'extrude002 = extrude(mySketch001, length = 50)'
|
'extrude002 = extrude(mySketch001, length = 50)'
|
||||||
)
|
)
|
||||||
|
|
||||||
await acceptBtn.click()
|
await acceptBtn.click()
|
||||||
await expect(successToast).not.toBeVisible()
|
await expect(successToast).not.toBeVisible()
|
||||||
})
|
})
|
||||||
}
|
})
|
||||||
)
|
|
||||||
|
|
||||||
test('multiple body selections', async ({
|
test('multiple body selections', async ({
|
||||||
context,
|
context,
|
||||||
|
@ -483,10 +483,11 @@ extrude001 = extrude(sketch001, length = 50)
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
test.fixme(
|
test(
|
||||||
`Network health indicator only appears in modeling view`,
|
`Network health indicator only appears in modeling view`,
|
||||||
{ tag: '@electron' },
|
{ tag: '@electron' },
|
||||||
async ({ context, page }, testInfo) => {
|
async ({ context, page }, testInfo) => {
|
||||||
|
test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e')
|
||||||
await context.folderSetupFn(async (dir) => {
|
await context.folderSetupFn(async (dir) => {
|
||||||
const bracketDir = path.join(dir, 'bracket')
|
const bracketDir = path.join(dir, 'bracket')
|
||||||
await fsp.mkdir(bracketDir, { recursive: true })
|
await fsp.mkdir(bracketDir, { recursive: true })
|
||||||
|
@ -188,7 +188,8 @@ sketch001 = startProfileAt([12.34, -12.34], sketch002)
|
|||||||
page.getByRole('button', { name: 'Start Sketch' })
|
page.getByRole('button', { name: 'Start Sketch' })
|
||||||
).toBeVisible()
|
).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 (
|
const doEditSegmentsByDraggingHandle = async (
|
||||||
page: Page,
|
page: Page,
|
||||||
homePage: HomePageFixture,
|
homePage: HomePageFixture,
|
||||||
@ -1086,107 +1087,108 @@ profile001 = startProfileAt([${roundOff(scale * 69.6)}, ${roundOff(
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
// TODO: fix after electron migration is merged
|
// TODO: fix after electron migration is merged
|
||||||
test.fixme(
|
test('empty-scene default-planes act as expected', async ({
|
||||||
'empty-scene default-planes act as expected',
|
page,
|
||||||
async ({ page, homePage }) => {
|
homePage,
|
||||||
/**
|
}) => {
|
||||||
* Tests the following things
|
test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e')
|
||||||
* 1) The the planes are there on load because the scene is empty
|
/**
|
||||||
* 2) The planes don't changes color when hovered initially
|
* Tests the following things
|
||||||
* 3) Putting something in the scene makes the planes hidden
|
* 1) The the planes are there on load because the scene is empty
|
||||||
* 4) Removing everything from the scene shows the plans again
|
* 2) The planes don't changes color when hovered initially
|
||||||
* 3) Once "start sketch" is click, the planes do respond to hovers
|
* 3) Putting something in the scene makes the planes hidden
|
||||||
* 4) Selecting a plan works as expected, i.e. sketch mode
|
* 4) Removing everything from the scene shows the plans again
|
||||||
* 5) Reloading the scene with something already in the scene means the planes are hidden
|
* 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)
|
const u = await getUtils(page)
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
await u.openDebugPanel()
|
await u.openDebugPanel()
|
||||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||||
await u.closeDebugPanel()
|
await u.closeDebugPanel()
|
||||||
|
|
||||||
const XYPlanePoint = { x: 774, y: 116 } as const
|
const XYPlanePoint = { x: 774, y: 116 } as const
|
||||||
const unHoveredColor: [number, number, number] = [47, 47, 93]
|
const unHoveredColor: [number, number, number] = [47, 47, 93]
|
||||||
expect(
|
expect(
|
||||||
await u.getGreatestPixDiff(XYPlanePoint, unHoveredColor)
|
await u.getGreatestPixDiff(XYPlanePoint, unHoveredColor)
|
||||||
).toBeLessThan(8)
|
).toBeLessThan(8)
|
||||||
|
|
||||||
await page.mouse.move(XYPlanePoint.x, XYPlanePoint.y)
|
await page.mouse.move(XYPlanePoint.x, XYPlanePoint.y)
|
||||||
await page.waitForTimeout(200)
|
await page.waitForTimeout(200)
|
||||||
|
|
||||||
// color should not change for having been hovered
|
// color should not change for having been hovered
|
||||||
expect(
|
expect(
|
||||||
await u.getGreatestPixDiff(XYPlanePoint, unHoveredColor)
|
await u.getGreatestPixDiff(XYPlanePoint, unHoveredColor)
|
||||||
).toBeLessThan(8)
|
).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], %)
|
|> startProfileAt([-10, -10], %)
|
||||||
|> line(end = [20, 0])
|
|> line(end = [20, 0])
|
||||||
|> line(end = [0, 20])
|
|> line(end = [0, 20])
|
||||||
|> xLine(length = -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]
|
const noPlanesColor: [number, number, number] = [30, 30, 30]
|
||||||
expect(
|
expect(
|
||||||
await u.getGreatestPixDiff(XYPlanePoint, noPlanesColor)
|
await u.getGreatestPixDiff(XYPlanePoint, noPlanesColor)
|
||||||
).toBeLessThan(3)
|
).toBeLessThan(3)
|
||||||
|
|
||||||
await u.clearCommandLogs()
|
await u.clearCommandLogs()
|
||||||
await u.removeCurrentCode()
|
await u.removeCurrentCode()
|
||||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||||
|
|
||||||
await expect
|
await expect
|
||||||
.poll(() => u.getGreatestPixDiff(XYPlanePoint, unHoveredColor), {
|
.poll(() => u.getGreatestPixDiff(XYPlanePoint, unHoveredColor), {
|
||||||
timeout: 5_000,
|
timeout: 5_000,
|
||||||
})
|
})
|
||||||
.toBeLessThan(8)
|
.toBeLessThan(8)
|
||||||
|
|
||||||
// click start Sketch
|
// click start Sketch
|
||||||
await page.getByRole('button', { name: 'Start Sketch' }).click()
|
await page.getByRole('button', { name: 'Start Sketch' }).click()
|
||||||
await page.mouse.move(XYPlanePoint.x, XYPlanePoint.y, { steps: 50 })
|
await page.mouse.move(XYPlanePoint.x, XYPlanePoint.y, { steps: 50 })
|
||||||
const hoveredColor: [number, number, number] = [93, 93, 127]
|
const hoveredColor: [number, number, number] = [93, 93, 127]
|
||||||
// now that we're expecting the user to select a plan, it does respond to hover
|
// now that we're expecting the user to select a plan, it does respond to hover
|
||||||
await expect
|
await expect
|
||||||
.poll(() => u.getGreatestPixDiff(XYPlanePoint, hoveredColor))
|
.poll(() => u.getGreatestPixDiff(XYPlanePoint, hoveredColor))
|
||||||
.toBeLessThan(8)
|
.toBeLessThan(8)
|
||||||
|
|
||||||
await page.mouse.click(XYPlanePoint.x, XYPlanePoint.y)
|
await page.mouse.click(XYPlanePoint.x, XYPlanePoint.y)
|
||||||
await page.waitForTimeout(600)
|
await page.waitForTimeout(600)
|
||||||
|
|
||||||
await page.mouse.click(XYPlanePoint.x, XYPlanePoint.y)
|
await page.mouse.click(XYPlanePoint.x, XYPlanePoint.y)
|
||||||
await page.waitForTimeout(200)
|
await page.waitForTimeout(200)
|
||||||
await page.mouse.click(XYPlanePoint.x + 50, XYPlanePoint.y + 50)
|
await page.mouse.click(XYPlanePoint.x + 50, XYPlanePoint.y + 50)
|
||||||
await expect(u.codeLocator).toHaveText(`sketch001 = startSketchOn('XZ')
|
await expect(u.codeLocator).toHaveText(`sketch001 = startSketchOn('XZ')
|
||||||
|> startProfileAt([11.8, 9.09], %)
|
|> startProfileAt([11.8, 9.09], %)
|
||||||
|> line(end = [3.39, -3.39])
|
|> line(end = [3.39, -3.39])
|
||||||
`)
|
`)
|
||||||
|
|
||||||
await page.addInitScript(async () => {
|
await page.addInitScript(async () => {
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
'persistCode',
|
'persistCode',
|
||||||
`sketch001 = startSketchOn('XZ')
|
`sketch001 = startSketchOn('XZ')
|
||||||
|> startProfileAt([11.8, 9.09], %)
|
|> startProfileAt([11.8, 9.09], %)
|
||||||
|> line(end = [3.39, -3.39])
|
|> line(end = [3.39, -3.39])
|
||||||
`
|
`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
await u.openDebugPanel()
|
await u.openDebugPanel()
|
||||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||||
await u.closeDebugPanel()
|
await u.closeDebugPanel()
|
||||||
|
|
||||||
// expect there to be no planes on load since there's something in the scene
|
// expect there to be no planes on load since there's something in the scene
|
||||||
expect(
|
expect(
|
||||||
await u.getGreatestPixDiff(XYPlanePoint, noPlanesColor)
|
await u.getGreatestPixDiff(XYPlanePoint, noPlanesColor)
|
||||||
).toBeLessThan(3)
|
).toBeLessThan(3)
|
||||||
}
|
})
|
||||||
)
|
|
||||||
|
|
||||||
test('Can attempt to sketch on revolved face', async ({ page, homePage }) => {
|
test('Can attempt to sketch on revolved face', async ({ page, homePage }) => {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
@ -1460,10 +1462,11 @@ test.describe(`Sketching with offset planes`, () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
test.describe('multi-profile sketching', () => {
|
test.describe('multi-profile sketching', () => {
|
||||||
test.fixme(
|
test(
|
||||||
`test it removes half-finished expressions when changing tools in sketch mode`,
|
`test it removes half-finished expressions when changing tools in sketch mode`,
|
||||||
{ tag: ['@skipWin'] },
|
{ tag: ['@skipWin'] },
|
||||||
async ({ context, page, scene, toolbar, editor, homePage, cmdBar }) => {
|
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
|
// We seed the scene with a single offset plane
|
||||||
await context.addInitScript(() => {
|
await context.addInitScript(() => {
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
@ -2852,13 +2855,18 @@ loft([profile001, profile002])
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
test.fixme(
|
test('Can enter sketch loft edges offsetPlane and continue sketch', async ({
|
||||||
'Can enter sketch loft edges offsetPlane and continue sketch',
|
scene,
|
||||||
async ({ scene, toolbar, editor, page, homePage }) => {
|
toolbar,
|
||||||
await page.addInitScript(async () => {
|
editor,
|
||||||
localStorage.setItem(
|
page,
|
||||||
'persistCode',
|
homePage,
|
||||||
`sketch001 = startSketchOn('XZ')
|
}) => {
|
||||||
|
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)
|
profile001 = startProfileAt([34, 42.66], sketch001)
|
||||||
|> line(end = [102.65, 151.99])
|
|> line(end = [102.65, 151.99])
|
||||||
|> line(end = [76, -138.66])
|
|> line(end = [76, -138.66])
|
||||||
@ -2874,51 +2882,50 @@ profile002 = startProfileAt([39.43, 172.21], sketch002)
|
|||||||
|
|
||||||
loft([profile001, profile002])
|
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)
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
const [rect1Crn2] = scene.makeMouseHelpers(797, 268)
|
await homePage.goToModelingScene()
|
||||||
|
await expect(
|
||||||
|
page.getByRole('button', { name: 'Start Sketch' })
|
||||||
|
).not.toBeDisabled()
|
||||||
|
|
||||||
await scene.moveCameraTo(
|
const topProfileEdgeClickCoords = { x: 602, y: 185 } as const
|
||||||
{ x: 8171, y: -7740, z: 1624 },
|
const [topProfileEdgeClick] = scene.makeMouseHelpers(
|
||||||
{ x: 3302, y: -627, z: 2892 }
|
topProfileEdgeClickCoords.x,
|
||||||
)
|
topProfileEdgeClickCoords.y
|
||||||
|
)
|
||||||
|
const [sideProfileEdgeClick] = scene.makeMouseHelpers(788, 188)
|
||||||
|
|
||||||
await topProfileEdgeClick()
|
const [rect1Crn1] = scene.makeMouseHelpers(592, 283)
|
||||||
await page.waitForTimeout(300)
|
const [rect1Crn2] = scene.makeMouseHelpers(797, 268)
|
||||||
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 scene.moveCameraTo(
|
||||||
await page.waitForTimeout(100)
|
{ x: 8171, y: -7740, z: 1624 },
|
||||||
await rect1Crn1()
|
{ x: 3302, y: -627, z: 2892 }
|
||||||
await editor.expectEditor.toContain(
|
)
|
||||||
`profile003 = startProfileAt([47.76, -17.13], plane001)`
|
|
||||||
)
|
await topProfileEdgeClick()
|
||||||
await rect1Crn2()
|
await page.waitForTimeout(300)
|
||||||
await editor.expectEditor.toContain(
|
await toolbar.editSketch()
|
||||||
`angledLine([0, 106.42], %, $rectangleSegmentA001)`
|
await page.waitForTimeout(600)
|
||||||
)
|
await sideProfileEdgeClick()
|
||||||
await page.waitForTimeout(100)
|
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
|
// Regression test for https://github.com/KittyCAD/modeling-app/issues/4891
|
||||||
|
@ -36,10 +36,11 @@ test.setTimeout(60_000)
|
|||||||
// a snapshot of it feels weird. I'd rather our regular tests fail.
|
// 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
|
// The primary failure is doExport now relies on the filesystem. We can follow
|
||||||
// up with another PR if we want this back.
|
// up with another PR if we want this back.
|
||||||
test.skip(
|
test(
|
||||||
'exports of each format should work',
|
'exports of each format should work',
|
||||||
{ tag: ['@snapshot', '@skipWin', '@skipMacos'] },
|
{ tag: ['@snapshot', '@skipWin', '@skipMacos'] },
|
||||||
async ({ page, context, scene, cmdBar, tronApp }) => {
|
async ({ page, context, scene, cmdBar, tronApp }) => {
|
||||||
|
test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e')
|
||||||
if (!tronApp) {
|
if (!tronApp) {
|
||||||
fail()
|
fail()
|
||||||
}
|
}
|
||||||
@ -406,9 +407,6 @@ test(
|
|||||||
'Draft segments should look right',
|
'Draft segments should look right',
|
||||||
{ tag: '@snapshot' },
|
{ tag: '@snapshot' },
|
||||||
async ({ page, scene, toolbar }) => {
|
async ({ page, scene, toolbar }) => {
|
||||||
// FIXME: Skip on macos its being weird.
|
|
||||||
// test.skip(process.platform === 'darwin', 'Skip on macos')
|
|
||||||
|
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
await page.setViewportSize({ width: 1200, height: 500 })
|
await page.setViewportSize({ width: 1200, height: 500 })
|
||||||
const PUR = 400 / 37.5 //pixeltoUnitRatio
|
const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||||
@ -585,9 +583,6 @@ test(
|
|||||||
'Draft circle should look right',
|
'Draft circle should look right',
|
||||||
{ tag: '@snapshot' },
|
{ tag: '@snapshot' },
|
||||||
async ({ page, context, cmdBar, scene }) => {
|
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)
|
const u = await getUtils(page)
|
||||||
await page.setViewportSize({ width: 1200, height: 500 })
|
await page.setViewportSize({ width: 1200, height: 500 })
|
||||||
const PUR = 400 / 37.5 //pixeltoUnitRatio
|
const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||||
@ -952,9 +947,6 @@ test(
|
|||||||
)
|
)
|
||||||
|
|
||||||
test.describe('Grid visibility', { tag: '@snapshot' }, () => {
|
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 ({
|
test('Grid turned off to on via command bar', async ({
|
||||||
page,
|
page,
|
||||||
cmdBar,
|
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)
|
const u = await getUtils(page)
|
||||||
await context.addInitScript(async () => {
|
await context.addInitScript(async () => {
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
|
@ -3,11 +3,12 @@ import { commonPoints, getUtils } from './test-utils'
|
|||||||
import { EngineCommand } from 'lang/std/artifactGraph'
|
import { EngineCommand } from 'lang/std/artifactGraph'
|
||||||
import { uuidv4 } from 'lib/utils'
|
import { uuidv4 } from 'lib/utils'
|
||||||
|
|
||||||
test.fixme('Test network and connection issues', () => {
|
test.describe('Test network and connection issues', () => {
|
||||||
test(
|
test(
|
||||||
'simulate network down and network little widget',
|
'simulate network down and network little widget',
|
||||||
{ tag: '@skipLocalEngine' },
|
{ tag: '@skipLocalEngine' },
|
||||||
async ({ page, homePage }) => {
|
async ({ page, homePage }) => {
|
||||||
|
test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e')
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
@ -84,6 +85,7 @@ test.fixme('Test network and connection issues', () => {
|
|||||||
'Engine disconnect & reconnect in sketch mode',
|
'Engine disconnect & reconnect in sketch mode',
|
||||||
{ tag: '@skipLocalEngine' },
|
{ tag: '@skipLocalEngine' },
|
||||||
async ({ page, homePage, toolbar }) => {
|
async ({ page, homePage, toolbar }) => {
|
||||||
|
test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e')
|
||||||
const networkToggle = page.getByTestId('network-toggle')
|
const networkToggle = page.getByTestId('network-toggle')
|
||||||
|
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
|
@ -179,169 +179,170 @@ test.describe('Testing Camera Movement', { tag: ['@skipWin'] }, () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// TODO: fix after electron migration is merged
|
// TODO: fix after electron migration is merged
|
||||||
test.fixme(
|
test('Zoom should be consistent when exiting or entering sketches', async ({
|
||||||
'Zoom should be consistent when exiting or entering sketches',
|
page,
|
||||||
async ({ page, homePage }) => {
|
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
|
test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e')
|
||||||
// than again for sketching
|
// 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)
|
const u = await getUtils(page)
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await u.waitForPageLoad()
|
await u.waitForPageLoad()
|
||||||
await u.openDebugPanel()
|
await u.openDebugPanel()
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Start Sketch' })
|
page.getByRole('button', { name: 'Start Sketch' })
|
||||||
).not.toBeDisabled()
|
).not.toBeDisabled()
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Start Sketch' })
|
page.getByRole('button', { name: 'Start Sketch' })
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
|
|
||||||
// click on "Start Sketch" button
|
// click on "Start Sketch" button
|
||||||
await u.clearCommandLogs()
|
await u.clearCommandLogs()
|
||||||
await page.getByRole('button', { name: 'Start Sketch' }).click()
|
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)
|
await page.waitForTimeout(100)
|
||||||
|
await expect(page.getByTestId('hover-highlight')).not.toBeVisible({
|
||||||
// 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({
|
|
||||||
timeout: 10_000,
|
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 ({
|
test(`Zoom by scroll should not fire while orbiting`, async ({
|
||||||
homePage,
|
homePage,
|
||||||
|
@ -1005,114 +1005,108 @@ part002 = startSketchOn('XZ')
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
test.fixme(
|
test('Horizontally constrained line remains selected after applying constraint', async ({
|
||||||
'Horizontally constrained line remains selected after applying constraint',
|
page,
|
||||||
async ({ page, homePage }) => {
|
homePage,
|
||||||
test.setTimeout(70_000)
|
}) => {
|
||||||
await page.addInitScript(async () => {
|
test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e')
|
||||||
localStorage.setItem(
|
test.setTimeout(70_000)
|
||||||
'persistCode',
|
await page.addInitScript(async () => {
|
||||||
`sketch001 = startSketchOn('XY')
|
localStorage.setItem(
|
||||||
|
'persistCode',
|
||||||
|
`sketch001 = startSketchOn('XY')
|
||||||
|> startProfileAt([-1.05, -1.07], %)
|
|> startProfileAt([-1.05, -1.07], %)
|
||||||
|> line(end = [3.79, 2.68], tag = $seg01)
|
|> line(end = [3.79, 2.68], tag = $seg01)
|
||||||
|> line(end = [3.13, -2.4])`
|
|> 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)
|
.click()
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await page.waitForTimeout(500)
|
||||||
|
await page.getByRole('button', { name: 'Horizontal', exact: true }).click()
|
||||||
|
await page.waitForTimeout(500)
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
await pollEditorLinesSelectedLength(page, 1)
|
||||||
await u.waitForPageLoad()
|
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()
|
// Wait for code editor to settle.
|
||||||
await expect(
|
await page.waitForTimeout(2000)
|
||||||
page.getByRole('button', { name: 'Edit Sketch' })
|
|
||||||
).toBeEnabled({ timeout: 10_000 })
|
|
||||||
await page.getByRole('button', { name: 'Edit Sketch' }).click()
|
|
||||||
|
|
||||||
// Wait for overlays to populate
|
// If the overlay-angle is updated the THREE.js scene is in a good state
|
||||||
await page.waitForTimeout(1000)
|
await expect(
|
||||||
|
await page.locator('[data-overlay-index="1"]')
|
||||||
|
).toHaveAttribute('data-overlay-angle', '0')
|
||||||
|
|
||||||
await page.waitForTimeout(100)
|
const lineAfter = await u.getSegmentBodyCoords(
|
||||||
const lineBefore = await u.getSegmentBodyCoords(
|
`[data-overlay-index="1"]`,
|
||||||
`[data-overlay-index="1"]`,
|
0
|
||||||
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
|
const linebb = await u.getBoundingBox('[data-overlay-index="1"]')
|
||||||
.getByRole('button', {
|
await page.mouse.move(linebb.x, linebb.y, { steps: 25 })
|
||||||
name: 'Length: open menu',
|
await page.mouse.click(linebb.x, linebb.y)
|
||||||
})
|
|
||||||
.click()
|
|
||||||
await page.waitForTimeout(500)
|
|
||||||
await page
|
|
||||||
.getByRole('button', { name: 'Horizontal', exact: true })
|
|
||||||
.click()
|
|
||||||
await page.waitForTimeout(500)
|
|
||||||
|
|
||||||
await pollEditorLinesSelectedLength(page, 1)
|
await expect
|
||||||
let activeLinesContent = await page.locator('.cm-activeLine').all()
|
.poll(async () => await u.getGreatestPixDiff(lineAfter, TEST_COLORS.BLUE))
|
||||||
await expect(activeLinesContent[0]).toHaveText(`|> xLine(length = 3.13)`)
|
.toBeLessThan(3)
|
||||||
|
|
||||||
// Wait for code editor to settle.
|
await page.waitForTimeout(500)
|
||||||
await page.waitForTimeout(2000)
|
|
||||||
|
|
||||||
// If the overlay-angle is updated the THREE.js scene is in a good state
|
// await expect(page.getByRole('button', { name: 'length', exact: true })).toBeVisible()
|
||||||
await expect(
|
await page.waitForTimeout(200)
|
||||||
await page.locator('[data-overlay-index="1"]')
|
// await page.getByRole('button', { name: 'length', exact: true }).click()
|
||||||
).toHaveAttribute('data-overlay-angle', '0')
|
await page.getByTestId('constraint-length').click()
|
||||||
|
|
||||||
const lineAfter = await u.getSegmentBodyCoords(
|
await page.getByTestId('cmd-bar-arg-value').getByRole('textbox').fill('10')
|
||||||
`[data-overlay-index="1"]`,
|
await page
|
||||||
0
|
.getByRole('button', {
|
||||||
)
|
name: 'arrow right Continue',
|
||||||
|
})
|
||||||
|
.click()
|
||||||
|
|
||||||
const linebb = await u.getBoundingBox('[data-overlay-index="1"]')
|
await pollEditorLinesSelectedLength(page, 1)
|
||||||
await page.mouse.move(linebb.x, linebb.y, { steps: 25 })
|
activeLinesContent = await page.locator('.cm-activeLine').all()
|
||||||
await page.mouse.click(linebb.x, linebb.y)
|
await expect(activeLinesContent[0]).toHaveText(
|
||||||
|
`|> xLine(length = length001)`
|
||||||
|
)
|
||||||
|
|
||||||
await expect
|
// checking the count of the overlays is a good proxy check that the client sketch scene is in a good state
|
||||||
.poll(
|
await expect(page.getByTestId('segment-overlay')).toHaveCount(2)
|
||||||
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)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
test.describe('Electron constraint tests', () => {
|
test.describe('Electron constraint tests', () => {
|
||||||
test(
|
test(
|
||||||
|
@ -2,7 +2,8 @@ import { test, expect } from './zoo-test'
|
|||||||
import { getUtils } from './test-utils'
|
import { getUtils } from './test-utils'
|
||||||
|
|
||||||
test.describe('Test toggling perspective', () => {
|
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)
|
const u = await getUtils(page)
|
||||||
|
|
||||||
// Locators and constants
|
// Locators and constants
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -448,15 +448,20 @@ profile003 = startProfileAt([40.16, -120.48], sketch006)
|
|||||||
await page.waitForTimeout(200)
|
await page.waitForTimeout(200)
|
||||||
await expect(u.codeLocator).not.toContainText(codeToBeDeletedSnippet)
|
await expect(u.codeLocator).not.toContainText(codeToBeDeletedSnippet)
|
||||||
})
|
})
|
||||||
test.fixme(
|
test('parent Solid should be select and deletable and uses custom planes to position children', async ({
|
||||||
'parent Solid should be select and deletable and uses custom planes to position children',
|
page,
|
||||||
async ({ page, homePage, scene, cmdBar, editor }) => {
|
homePage,
|
||||||
test.setTimeout(90_000)
|
scene,
|
||||||
const u = await getUtils(page)
|
cmdBar,
|
||||||
await page.addInitScript(async () => {
|
editor,
|
||||||
localStorage.setItem(
|
}) => {
|
||||||
'persistCode',
|
test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e')
|
||||||
`part001 = startSketchOn('XY')
|
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)
|
yo = startProfileAt([4.83, 12.56], part001)
|
||||||
|> line(end = [15.1, 2.48])
|
|> line(end = [15.1, 2.48])
|
||||||
|> line(end = [3.15, -9.85], tag = $seg01)
|
|> line(end = [3.15, -9.85], tag = $seg01)
|
||||||
@ -487,35 +492,34 @@ profile001 = startProfileAt([7.49, 9.96], sketch001)
|
|||||||
|> close()
|
|> 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()
|
}, KCL_DEFAULT_LENGTH)
|
||||||
await page.keyboard.press('Delete')
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
await u.expectCmdLog('[data-message-type="execution-done"]', 10_000)
|
|
||||||
await page.waitForTimeout(200)
|
|
||||||
|
|
||||||
await editor.expectEditor.not.toContain(`yoo = extrude(yo, length = 4)`, {
|
await homePage.goToModelingScene()
|
||||||
shouldNormalise: true,
|
await scene.settled(cmdBar)
|
||||||
})
|
|
||||||
await editor.expectEditor.toContain(`startSketchOn({plane={origin`, {
|
const extrudeWall = { x: 575, y: 238 }
|
||||||
shouldNormalise: true,
|
|
||||||
})
|
// DELETE with selection on face of parent
|
||||||
await editor.snapshot()
|
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 ({
|
test('Hovering over 3d features highlights code, clicking puts the cursor in the right place and sends selection id to engine', async ({
|
||||||
page,
|
page,
|
||||||
homePage,
|
homePage,
|
||||||
|
@ -55,91 +55,87 @@ test.describe('Testing settings', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// The behavior is actually broken. Parent always takes precedence
|
// The behavior is actually broken. Parent always takes precedence
|
||||||
test.fixme(
|
test('Project settings can be set and override user settings', async ({
|
||||||
'Project settings can be set and override user settings',
|
page,
|
||||||
async ({ page, homePage }) => {
|
homePage,
|
||||||
const u = await getUtils(page)
|
}) => {
|
||||||
await test.step(`Setup`, async () => {
|
test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e')
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
const u = await getUtils(page)
|
||||||
await homePage.goToModelingScene()
|
await test.step(`Setup`, async () => {
|
||||||
await page
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
.getByRole('button', { name: 'Start Sketch' })
|
await homePage.goToModelingScene()
|
||||||
.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()
|
|
||||||
await page
|
await page
|
||||||
.getByRole('button', {
|
.getByRole('button', { name: 'Start Sketch' })
|
||||||
name: 'Roll back show debug panel',
|
.waitFor({ state: 'visible' })
|
||||||
})
|
})
|
||||||
.click()
|
|
||||||
await expect(inputLocator).not.toBeChecked()
|
|
||||||
|
|
||||||
// Check that the project setting did not change
|
// Selectors and constants
|
||||||
await page.getByRole('radio', { name: 'Project' }).click()
|
const paneButtonLocator = page.getByTestId('debug-pane-button')
|
||||||
await expect(
|
const headingLocator = page.getByRole('heading', {
|
||||||
page.locator('input[name="app-showDebugPanel"]')
|
name: 'Settings',
|
||||||
).not.toBeChecked()
|
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 ({
|
test('Keybindings display the correct hotkey for Command Palette', async ({
|
||||||
page,
|
page,
|
||||||
@ -175,103 +171,98 @@ test.describe('Testing settings', () => {
|
|||||||
await expect(hotkey).toHaveText(text)
|
await expect(hotkey).toHaveText(text)
|
||||||
})
|
})
|
||||||
|
|
||||||
test.fixme(
|
test('Project and user settings can be reset', async ({ page, homePage }) => {
|
||||||
'Project and user settings can be reset',
|
test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e')
|
||||||
async ({ page, homePage }) => {
|
const u = await getUtils(page)
|
||||||
const u = await getUtils(page)
|
await test.step(`Setup`, async () => {
|
||||||
await test.step(`Setup`, async () => {
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await homePage.goToModelingScene()
|
||||||
await homePage.goToModelingScene()
|
await u.waitForPageLoad()
|
||||||
await u.waitForPageLoad()
|
await page.waitForTimeout(1000)
|
||||||
await page.waitForTimeout(1000)
|
})
|
||||||
})
|
|
||||||
|
// Selectors and constants
|
||||||
// Selectors and constants
|
const projectSettingsTab = page.getByRole('radio', { name: 'Project' })
|
||||||
const projectSettingsTab = page.getByRole('radio', { name: 'Project' })
|
const userSettingsTab = page.getByRole('radio', { name: 'User' })
|
||||||
const userSettingsTab = page.getByRole('radio', { name: 'User' })
|
const resetButton = (level: SettingsLevel) =>
|
||||||
const resetButton = (level: SettingsLevel) =>
|
page.getByRole('button', {
|
||||||
page.getByRole('button', {
|
name: `Reset ${level}-level settings`,
|
||||||
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)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
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`,
|
`Project settings override user settings on desktop`,
|
||||||
{ tag: ['@electron', '@skipWin'] },
|
{ tag: ['@electron', '@skipWin'] },
|
||||||
async ({ context, page }, testInfo) => {
|
async ({ context, page }, testInfo) => {
|
||||||
test.skip(
|
test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e')
|
||||||
process.platform === 'win32',
|
|
||||||
'TODO: remove this skip https://github.com/KittyCAD/modeling-app/issues/3557'
|
|
||||||
)
|
|
||||||
const projectName = 'bracket'
|
const projectName = 'bracket'
|
||||||
const { dir: projectDirName } = await context.folderSetupFn(
|
const { dir: projectDirName } = await context.folderSetupFn(
|
||||||
async (dir) => {
|
async (dir) => {
|
||||||
@ -407,12 +398,13 @@ test.describe('Testing settings', () => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// It was much easier to test the logo color than the background stream color.
|
// 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',
|
'user settings reload on external change, on project and modeling view',
|
||||||
{
|
{
|
||||||
tag: '@electron',
|
tag: '@electron',
|
||||||
},
|
},
|
||||||
async ({ context, page, tronApp }, testInfo) => {
|
async ({ context, page, tronApp }, testInfo) => {
|
||||||
|
test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e')
|
||||||
if (!tronApp) {
|
if (!tronApp) {
|
||||||
fail()
|
fail()
|
||||||
}
|
}
|
||||||
@ -466,10 +458,11 @@ test.describe('Testing settings', () => {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
test.fixme(
|
test(
|
||||||
'project settings reload on external change',
|
'project settings reload on external change',
|
||||||
{ tag: '@electron' },
|
{ tag: '@electron' },
|
||||||
async ({ context, page }, testInfo) => {
|
async ({ context, page }, testInfo) => {
|
||||||
|
test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e')
|
||||||
const { dir: projectDirName } = await context.folderSetupFn(
|
const { dir: projectDirName } = await context.folderSetupFn(
|
||||||
async () => {}
|
async () => {}
|
||||||
)
|
)
|
||||||
@ -982,63 +975,68 @@ fn cube`
|
|||||||
/**
|
/**
|
||||||
* This test assumes that the default value of the "highlight edges" setting is "on".
|
* This test assumes that the default value of the "highlight edges" setting is "on".
|
||||||
*/
|
*/
|
||||||
test.fixme(
|
test(`Toggle stream settings multiple times`, async ({
|
||||||
`Toggle stream settings multiple times`,
|
page,
|
||||||
async ({ page, scene, homePage, context, toolbar, cmdBar }, testInfo) => {
|
scene,
|
||||||
await context.folderSetupFn(async (dir) => {
|
homePage,
|
||||||
const projectDir = join(dir, 'project-000')
|
context,
|
||||||
await fsp.mkdir(projectDir, { recursive: true })
|
toolbar,
|
||||||
await fsp.copyFile(
|
cmdBar,
|
||||||
executorInputPath('cube.kcl'),
|
}, testInfo) => {
|
||||||
join(projectDir, 'main.kcl')
|
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 test.step(`First snapshot`, async () => {
|
||||||
await homePage.openProject('project-000')
|
await homePage.openProject('project-000')
|
||||||
await toolbar.closePane('code')
|
await toolbar.closePane('code')
|
||||||
await expect(toolbar.startSketchBtn).toBeEnabled({ timeout: 20_000 })
|
await expect(toolbar.startSketchBtn).toBeEnabled({ timeout: 20_000 })
|
||||||
await scene.clickNoWhere()
|
await scene.clickNoWhere()
|
||||||
})
|
})
|
||||||
|
|
||||||
const toast = (value: boolean) =>
|
const toast = (value: boolean) =>
|
||||||
page.getByText(
|
page.getByText(
|
||||||
`Set highlight edges to "${String(value)}" as a user default`
|
`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')],
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
await test.step(`Toggle highlightEdges on`, async () => {
|
await test.step(`Toggle highlightEdges off`, async () => {
|
||||||
await cmdBar.openCmdBar()
|
await cmdBar.openCmdBar()
|
||||||
await cmdBar.chooseCommand('Settings · modeling · highlight edges')
|
await cmdBar.chooseCommand('Settings · modeling · highlight edges')
|
||||||
await cmdBar.selectOption({ name: 'on' }).click()
|
await cmdBar.selectOption({ name: 'off' }).click()
|
||||||
const trueToast = toast(true)
|
const falseToast = toast(false)
|
||||||
await expect(trueToast).toBeVisible()
|
await expect(falseToast).toBeVisible()
|
||||||
await trueToast.waitFor({ state: 'detached' })
|
await falseToast.waitFor({ state: 'detached' })
|
||||||
})
|
})
|
||||||
|
|
||||||
await expect(scene.streamWrapper).toHaveScreenshot(
|
await expect(scene.streamWrapper).not.toHaveScreenshot(
|
||||||
'toggle-settings-initial.png',
|
'toggle-settings-initial.png',
|
||||||
{
|
{
|
||||||
maxDiffPixels: 15,
|
maxDiffPixels: 15,
|
||||||
mask: [page.getByTestId('model-state-indicator')],
|
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')],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -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
|
// 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',
|
'can do many at once and get many prompts back, and interact with many',
|
||||||
{ tag: ['@skipWin'] },
|
{ tag: ['@skipWin'] },
|
||||||
async ({ page, homePage }) => {
|
async ({ page, homePage }) => {
|
||||||
|
test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e')
|
||||||
// Let this test run longer since we've seen it timeout.
|
// Let this test run longer since we've seen it timeout.
|
||||||
test.setTimeout(180_000)
|
test.setTimeout(180_000)
|
||||||
|
|
||||||
@ -619,10 +620,11 @@ async function sendPromptFromCommandBar(page: Page, promptStr: string) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
test.fixme(
|
test(
|
||||||
'Text-to-CAD functionality',
|
'Text-to-CAD functionality',
|
||||||
{ tag: '@electron' },
|
{ tag: '@electron' },
|
||||||
async ({ context, page }, testInfo) => {
|
async ({ context, page }, testInfo) => {
|
||||||
|
test.fixme(process.env.GITHUB_HEAD_REF !== 'all-e2e')
|
||||||
const projectName = 'project-000'
|
const projectName = 'project-000'
|
||||||
const prompt = 'lego 2x4'
|
const prompt = 'lego 2x4'
|
||||||
const textToCadFileName = 'lego-2x4.kcl'
|
const textToCadFileName = 'lego-2x4.kcl'
|
||||||
|
@ -2,7 +2,8 @@ import { test, expect } from './zoo-test'
|
|||||||
|
|
||||||
import { doExport, getUtils, makeTemplate } from './test-utils'
|
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 page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
@ -263,186 +264,187 @@ test('First escape in tool pops you out of tool, second exits sketch mode', asyn
|
|||||||
).not.toBeVisible()
|
).not.toBeVisible()
|
||||||
})
|
})
|
||||||
|
|
||||||
test.fixme(
|
test('Basic default modeling and sketch hotkeys work', async ({
|
||||||
'Basic default modeling and sketch hotkeys work',
|
page,
|
||||||
async ({ page, homePage }) => {
|
homePage,
|
||||||
const u = await getUtils(page)
|
}) => {
|
||||||
|
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
|
// This test can run long if it takes a little too long to load
|
||||||
// the engine.
|
// the engine.
|
||||||
test.setTimeout(90000)
|
test.setTimeout(90000)
|
||||||
// This test has a weird bug on ubuntu
|
// This test has a weird bug on ubuntu
|
||||||
// Funny, it's flaking on Windows too :). I think there is just something
|
// Funny, it's flaking on Windows too :). I think there is just something
|
||||||
// actually wrong.
|
// actually wrong.
|
||||||
test.skip(
|
test.skip(
|
||||||
process.platform === 'linux',
|
process.platform === 'linux',
|
||||||
'weird playwright bug on ubuntu https://github.com/KittyCAD/modeling-app/issues/2444'
|
'weird playwright bug on ubuntu https://github.com/KittyCAD/modeling-app/issues/2444'
|
||||||
)
|
)
|
||||||
// Load the app with the code pane open
|
// Load the app with the code pane open
|
||||||
|
|
||||||
await test.step(`Set up test`, async () => {
|
await test.step(`Set up test`, async () => {
|
||||||
await page.addInitScript(async () => {
|
await page.addInitScript(async () => {
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
'store',
|
'store',
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
state: {
|
state: {
|
||||||
openPanes: ['code'],
|
openPanes: ['code'],
|
||||||
},
|
},
|
||||||
version: 0,
|
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 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 () => {
|
const codePane = page.locator('.cm-content')
|
||||||
// Since there's code now, we have to get to the end of the line
|
const lineButton = page.getByRole('button', {
|
||||||
await page.locator('.cm-line').last().click()
|
name: 'line Line',
|
||||||
await page.keyboard.down('ControlOrMeta')
|
exact: true,
|
||||||
await page.keyboard.press('ArrowRight')
|
})
|
||||||
await page.keyboard.up('ControlOrMeta')
|
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 test.step(`Type code with modeling hotkeys, shouldn't fire`, async () => {
|
||||||
await page.keyboard.type('//')
|
await codePane.click()
|
||||||
await page.keyboard.press('l')
|
await page.keyboard.type('//')
|
||||||
await expect(lineButton).toHaveAttribute('aria-pressed', 'true')
|
await page.keyboard.press('s')
|
||||||
await page.keyboard.press('a')
|
await expect(commandBarComboBox).not.toBeVisible()
|
||||||
await expect(lineButton).toHaveAttribute('aria-pressed', 'true')
|
await page.keyboard.press('e')
|
||||||
await expect(codePane).toContainText('//la')
|
await expect(commandBarComboBox).not.toBeVisible()
|
||||||
await page.keyboard.press('Backspace')
|
await expect(codePane).toHaveText('//se')
|
||||||
await page.keyboard.press('Backspace')
|
})
|
||||||
await page.keyboard.press('Backspace')
|
|
||||||
await page.keyboard.press('Backspace')
|
// 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 () => {
|
// Use some sketch hotkeys to create a sketch (l and a for now)
|
||||||
await blurCodeEditor()
|
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.move(700, 200, { steps: 5 })
|
||||||
await page.mouse.click(700, 200)
|
await page.mouse.click(700, 200)
|
||||||
// On close it will unequip the line tool.
|
await page.mouse.move(800, 250, { steps: 5 })
|
||||||
await expect(lineButton).toHaveAttribute('aria-pressed', 'false')
|
await page.mouse.click(800, 250)
|
||||||
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(`Unequip line tool`, async () => {
|
||||||
await test.step(`Extrude the sketch`, async () => {
|
await page.keyboard.press('l')
|
||||||
await page.mouse.click(750, 150)
|
await expect(lineButton).not.toHaveAttribute('aria-pressed', 'true')
|
||||||
await blurCodeEditor()
|
})
|
||||||
await expect(extrudeButton).toBeEnabled()
|
|
||||||
await page.keyboard.press('e')
|
await test.step(`Draw a tangential arc`, async () => {
|
||||||
await page.waitForTimeout(500)
|
await page.keyboard.press('a')
|
||||||
await page.mouse.move(800, 200, { steps: 5 })
|
await expect(arcButton).toHaveAttribute('aria-pressed', 'true', {
|
||||||
await page.mouse.click(800, 200)
|
timeout: 10_000,
|
||||||
await expect(page.getByRole('button', { name: 'Continue' })).toBeVisible({
|
|
||||||
timeout: 20_000,
|
|
||||||
})
|
})
|
||||||
await page.getByRole('button', { name: 'Continue' }).click()
|
await page.mouse.move(1000, 100, { steps: 5 })
|
||||||
await expect(
|
await page.mouse.click(1000, 100)
|
||||||
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 test.step(`Unequip with escape, equip line tool`, async () => {
|
||||||
// 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.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 }) => {
|
test('Delete key does not navigate back', async ({ page, homePage }) => {
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
Reference in New Issue
Block a user