Compare commits
22 Commits
jtran/fix-
...
multi-sket
Author | SHA1 | Date | |
---|---|---|---|
91df25cd79 | |||
107bc1da9c | |||
b63c2fe915 | |||
3b6eee2320 | |||
d84457f8ea | |||
815e31347a | |||
620bbf2092 | |||
7b01b3967c | |||
92ab06f7f2 | |||
646ef71319 | |||
ce258dbc2e | |||
34e76880d5 | |||
2a099f8243 | |||
8e19c90e01 | |||
78de3325df | |||
0a842bc1d6 | |||
2257333bf3 | |||
48a4a635ba | |||
22c74fcd24 | |||
bc6b6fb3b3 | |||
d348d7dfd9 | |||
665416e6a2 |
@ -2458,44 +2458,6 @@ test.describe('Onboarding tests', () => {
|
|||||||
await expect(onboardingOverlayLocator).toBeVisible()
|
await expect(onboardingOverlayLocator).toBeVisible()
|
||||||
await expect(onboardingOverlayLocator).toContainText('the menu button')
|
await expect(onboardingOverlayLocator).toContainText('the menu button')
|
||||||
})
|
})
|
||||||
|
|
||||||
test("Avatar text doesn't mention avatar when no avatar", async ({
|
|
||||||
page,
|
|
||||||
}) => {
|
|
||||||
// Override beforeEach test setup
|
|
||||||
await page.addInitScript(
|
|
||||||
async ({ settingsKey, settings }) => {
|
|
||||||
localStorage.setItem(settingsKey, settings)
|
|
||||||
localStorage.setItem('FORCE_NO_IMAGE', 'FORCE_NO_IMAGE')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
settingsKey: TEST_SETTINGS_KEY,
|
|
||||||
settings: TOML.stringify({
|
|
||||||
settings: TEST_SETTINGS_ONBOARDING_USER_MENU,
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
const u = await getUtils(page)
|
|
||||||
await page.setViewportSize({ width: 1200, height: 500 })
|
|
||||||
await u.waitForAuthSkipAppStart()
|
|
||||||
|
|
||||||
await page.waitForURL('**/file/**', { waitUntil: 'domcontentloaded' })
|
|
||||||
|
|
||||||
// Test that the text in this step is correct
|
|
||||||
const avatarLocator = await page
|
|
||||||
.getByTestId('user-sidebar-toggle')
|
|
||||||
.locator('img')
|
|
||||||
const onboardingOverlayLocator = await page
|
|
||||||
.getByTestId('onboarding-content')
|
|
||||||
.locator('div')
|
|
||||||
.nth(1)
|
|
||||||
|
|
||||||
// Expect the avatar to be visible and for the text to reference it
|
|
||||||
await expect(avatarLocator).not.toBeVisible()
|
|
||||||
await expect(onboardingOverlayLocator).toBeVisible()
|
|
||||||
await expect(onboardingOverlayLocator).toContainText('the menu button')
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
test.describe('Testing selections', () => {
|
test.describe('Testing selections', () => {
|
||||||
@ -4601,53 +4563,6 @@ test.describe('Sketch tests', () => {
|
|||||||
await doSnapAtDifferentScales(page, [0, 10000, 10000])
|
await doSnapAtDifferentScales(page, [0, 10000, 10000])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
test('exiting a close extrude, has the extrude button enabled ready to go', async ({
|
|
||||||
page,
|
|
||||||
}) => {
|
|
||||||
// this was a regression https://github.com/KittyCAD/modeling-app/issues/2832
|
|
||||||
await page.addInitScript(async () => {
|
|
||||||
localStorage.setItem(
|
|
||||||
'persistCode',
|
|
||||||
`const sketch001 = startSketchOn('XZ')
|
|
||||||
|> startProfileAt([-0.45, 0.87], %)
|
|
||||||
|> line([1.32, 0.38], %)
|
|
||||||
|> line([1.02, -1.32], %, $seg01)
|
|
||||||
|> line([-1.01, -0.77], %)
|
|
||||||
|> lineTo([profileStartX(%), profileStartY(%)], %)
|
|
||||||
|> close(%)
|
|
||||||
`
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
const u = await getUtils(page)
|
|
||||||
await page.setViewportSize({ width: 1200, height: 500 })
|
|
||||||
|
|
||||||
await u.waitForAuthSkipAppStart()
|
|
||||||
|
|
||||||
// click "line([1.32, 0.38], %)"
|
|
||||||
await page.getByText(`line([1.32, 0.38], %)`).click()
|
|
||||||
await page.waitForTimeout(100)
|
|
||||||
// click edit sketch
|
|
||||||
await page.getByRole('button', { name: 'Edit Sketch' }).click()
|
|
||||||
await page.waitForTimeout(600) // wait for animation
|
|
||||||
|
|
||||||
// exit sketch
|
|
||||||
await page.getByRole('button', { name: 'Exit Sketch' }).click()
|
|
||||||
|
|
||||||
// expect extrude button to be enabled
|
|
||||||
await expect(
|
|
||||||
page.getByRole('button', { name: 'Extrude' })
|
|
||||||
).not.toBeDisabled()
|
|
||||||
|
|
||||||
// click extrude
|
|
||||||
await page.getByRole('button', { name: 'Extrude' }).click()
|
|
||||||
|
|
||||||
// sketch selection should already have been made. "Selection 1 face" only show up when the selection has been made already
|
|
||||||
// otherwise the cmdbar would be waiting for a selection.
|
|
||||||
await expect(
|
|
||||||
page.getByRole('button', { name: 'Selection 1 face' })
|
|
||||||
).toBeVisible()
|
|
||||||
})
|
|
||||||
test("Existing sketch with bad code delete user's code", async ({ page }) => {
|
test("Existing sketch with bad code delete user's code", async ({ page }) => {
|
||||||
// this was a regression https://github.com/KittyCAD/modeling-app/issues/2832
|
// this was a regression https://github.com/KittyCAD/modeling-app/issues/2832
|
||||||
await page.addInitScript(async () => {
|
await page.addInitScript(async () => {
|
||||||
|
@ -857,11 +857,6 @@ export class SceneEntities {
|
|||||||
let addingNewSegmentStatus: 'nothing' | 'pending' | 'added' = 'nothing'
|
let addingNewSegmentStatus: 'nothing' | 'pending' | 'added' = 'nothing'
|
||||||
sceneInfra.setCallbacks({
|
sceneInfra.setCallbacks({
|
||||||
onDragEnd: async () => {
|
onDragEnd: async () => {
|
||||||
// After the user drags, code has been updated, and source ranges are
|
|
||||||
// potentially stale.
|
|
||||||
const astResult = kclManager.updateSourceRanges()
|
|
||||||
if (trap(astResult)) return
|
|
||||||
|
|
||||||
if (addingNewSegmentStatus !== 'nothing') {
|
if (addingNewSegmentStatus !== 'nothing') {
|
||||||
await this.tearDownSketch({ removeAxis: false })
|
await this.tearDownSketch({ removeAxis: false })
|
||||||
this.setupSketch({
|
this.setupSketch({
|
||||||
|
@ -35,7 +35,6 @@ import {
|
|||||||
canExtrudeSelection,
|
canExtrudeSelection,
|
||||||
handleSelectionBatch,
|
handleSelectionBatch,
|
||||||
isSelectionLastLine,
|
isSelectionLastLine,
|
||||||
isRangeInbetweenCharacters,
|
|
||||||
isSketchPipe,
|
isSketchPipe,
|
||||||
updateSelections,
|
updateSelections,
|
||||||
} from 'lib/selections'
|
} from 'lib/selections'
|
||||||
@ -426,7 +425,6 @@ export const ModelingMachineProvider = ({
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
selectionRanges.codeBasedSelections.length === 0 ||
|
selectionRanges.codeBasedSelections.length === 0 ||
|
||||||
isRangeInbetweenCharacters(selectionRanges) ||
|
|
||||||
isSelectionLastLine(selectionRanges, codeManager.code)
|
isSelectionLastLine(selectionRanges, codeManager.code)
|
||||||
) {
|
) {
|
||||||
// they have no selection, we should enable the button
|
// they have no selection, we should enable the button
|
||||||
|
@ -154,16 +154,6 @@ export class KclManager {
|
|||||||
this._executeCallback = callback
|
this._executeCallback = callback
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSourceRanges(): Error | null {
|
|
||||||
const newAst = parse(recast(this.ast))
|
|
||||||
if (err(newAst)) {
|
|
||||||
return newAst
|
|
||||||
}
|
|
||||||
|
|
||||||
this.ast = newAst
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
clearAst() {
|
clearAst() {
|
||||||
this._ast = {
|
this._ast = {
|
||||||
body: [],
|
body: [],
|
||||||
|
@ -360,14 +360,6 @@ export function isSelectionLastLine(
|
|||||||
return selectionRanges.codeBasedSelections[i].range[1] === code.length
|
return selectionRanges.codeBasedSelections[i].range[1] === code.length
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isRangeInbetweenCharacters(selectionRanges: Selections) {
|
|
||||||
return (
|
|
||||||
selectionRanges.codeBasedSelections.length === 1 &&
|
|
||||||
selectionRanges.codeBasedSelections[0].range[0] === 0 &&
|
|
||||||
selectionRanges.codeBasedSelections[0].range[1] === 0
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export type CommonASTNode = {
|
export type CommonASTNode = {
|
||||||
selection: Selection
|
selection: Selection
|
||||||
ast: Program
|
ast: Program
|
||||||
|
@ -126,17 +126,11 @@ async function getUser(context: UserContext) {
|
|||||||
if (!token && isTauri()) return Promise.reject(new Error('No token found'))
|
if (!token && isTauri()) return Promise.reject(new Error('No token found'))
|
||||||
if (token) headers['Authorization'] = `Bearer ${context.token}`
|
if (token) headers['Authorization'] = `Bearer ${context.token}`
|
||||||
|
|
||||||
if (SKIP_AUTH) {
|
if (SKIP_AUTH)
|
||||||
// For local tests
|
|
||||||
if (localStorage.getItem('FORCE_NO_IMAGE')) {
|
|
||||||
LOCAL_USER.image = ''
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
user: LOCAL_USER,
|
user: LOCAL_USER,
|
||||||
token,
|
token,
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const userPromise = !isTauri()
|
const userPromise = !isTauri()
|
||||||
? fetch(url, {
|
? fetch(url, {
|
||||||
@ -150,11 +144,6 @@ async function getUser(context: UserContext) {
|
|||||||
|
|
||||||
const user = await userPromise
|
const user = await userPromise
|
||||||
|
|
||||||
// Necessary here because we use Kurt's API key in CI
|
|
||||||
if (localStorage.getItem('FORCE_NO_IMAGE')) {
|
|
||||||
user.image = ''
|
|
||||||
}
|
|
||||||
|
|
||||||
if ('error_code' in user) return Promise.reject(new Error(user.message))
|
if ('error_code' in user) return Promise.reject(new Error(user.message))
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -2,18 +2,13 @@ import { OnboardingButtons, useDismiss, useNextClick } from '.'
|
|||||||
import { onboardingPaths } from 'routes/Onboarding/paths'
|
import { onboardingPaths } from 'routes/Onboarding/paths'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { useModelingContext } from 'hooks/useModelingContext'
|
import { useModelingContext } from 'hooks/useModelingContext'
|
||||||
import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
|
|
||||||
|
|
||||||
export default function UserMenu() {
|
export default function UserMenu() {
|
||||||
const { context } = useModelingContext()
|
const { context } = useModelingContext()
|
||||||
const { auth } = useSettingsAuthContext()
|
|
||||||
const dismiss = useDismiss()
|
const dismiss = useDismiss()
|
||||||
const next = useNextClick(onboardingPaths.PROJECT_MENU)
|
const next = useNextClick(onboardingPaths.PROJECT_MENU)
|
||||||
const [avatarErrored, setAvatarErrored] = useState(false)
|
const [avatarErrored, setAvatarErrored] = useState(false)
|
||||||
|
const buttonDescription = !avatarErrored ? 'your avatar' : 'the menu button'
|
||||||
const user = auth?.context?.user
|
|
||||||
const errorOrNoImage = !user?.image || avatarErrored
|
|
||||||
const buttonDescription = errorOrNoImage ? 'the menu button' : 'your avatar'
|
|
||||||
|
|
||||||
// Set up error handling for the user's avatar image,
|
// Set up error handling for the user's avatar image,
|
||||||
// so the onboarding text can be updated if it fails to load.
|
// so the onboarding text can be updated if it fails to load.
|
||||||
|
Reference in New Issue
Block a user