Merge branch 'main' into pierremtb/issue2610
This commit is contained in:
		
							
								
								
									
										33
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										33
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							@ -13,6 +13,7 @@ on:
 | 
			
		||||
  # Will checkout the last commit from the default branch (main as of 2023-10-04)
 | 
			
		||||
 | 
			
		||||
env:
 | 
			
		||||
  CUT_RELEASE_PR: ${{ github.event_name == 'pull_request' && (contains(github.event.pull_request.title, 'Cut release v')) }}
 | 
			
		||||
  BUILD_RELEASE: ${{ github.event_name == 'release' || github.event_name == 'schedule' || github.event_name == 'pull_request' && (contains(github.event.pull_request.title, 'Cut release v')) }}
 | 
			
		||||
 | 
			
		||||
concurrency:
 | 
			
		||||
@ -110,8 +111,14 @@ jobs:
 | 
			
		||||
          echo "$(jq --arg name 'Zoo Modeling App (Nightly)' \
 | 
			
		||||
            '.productName=$name' src-tauri/tauri.release.conf.json --indent 2)" > src-tauri/tauri.release.conf.json
 | 
			
		||||
 | 
			
		||||
      - name: Set updater test version
 | 
			
		||||
        if: env.CUT_RELEASE_PR
 | 
			
		||||
        run: |
 | 
			
		||||
          echo "$(jq --arg url 'https://dl.zoo.dev/releases/modeling-app/test/last_update.json' \
 | 
			
		||||
            '.plugins.updater.endpoints[]=$url' src-tauri/tauri.release.conf.json --indent 2)" > src-tauri/tauri.release.conf.json
 | 
			
		||||
 | 
			
		||||
      - uses: actions/upload-artifact@v3
 | 
			
		||||
        if: github.event_name == 'schedule'
 | 
			
		||||
        if: ${{ github.event_name == 'schedule' || env.CUT_RELEASE_PR }}
 | 
			
		||||
        with:
 | 
			
		||||
          path: |
 | 
			
		||||
            package.json
 | 
			
		||||
@ -379,6 +386,30 @@ jobs:
 | 
			
		||||
          E2E_TAURI_ENABLED: true
 | 
			
		||||
          TS_NODE_COMPILER_OPTIONS: '{"module": "commonjs"}'
 | 
			
		||||
 | 
			
		||||
      - uses: actions/download-artifact@v3
 | 
			
		||||
        if: env.CUT_RELEASE_PR
 | 
			
		||||
 | 
			
		||||
      - name: Copy updated .json file for updater test
 | 
			
		||||
        if: env.CUT_RELEASE_PR
 | 
			
		||||
        run: |
 | 
			
		||||
          ls -l artifact
 | 
			
		||||
          cp artifact/src-tauri/tauri.release.conf.json src-tauri/tauri.release.conf.json
 | 
			
		||||
          cat src-tauri/tauri.release.conf.json
 | 
			
		||||
 | 
			
		||||
      - name: Build the app (release, updater test)
 | 
			
		||||
        if: ${{ env.CUT_RELEASE_PR && matrix.os != 'ubuntu-latest' }}
 | 
			
		||||
        env:
 | 
			
		||||
          TAURI_CONF_ARGS: "-c ${{ matrix.os == 'windows-latest' && 'src-tauri\\tauri.release.conf.json' || 'src-tauri/tauri.release.conf.json' }}"
 | 
			
		||||
          TAURI_BUNDLE_ARGS: "-b ${{ matrix.os == 'windows-latest' && 'msi' || 'dmg' }}"
 | 
			
		||||
        run: "yarn tauri build ${{ env.TAURI_CONF_ARGS }} ${{ env.TAURI_BUNDLE_ARGS }} ${{ env.TAURI_ARGS_MACOS }}"
 | 
			
		||||
 | 
			
		||||
      - uses: actions/upload-artifact@v3
 | 
			
		||||
        if: ${{ env.CUT_RELEASE_PR && matrix.os != 'ubuntu-latest' }}
 | 
			
		||||
        with:
 | 
			
		||||
          path: "${{ matrix.os == 'macos-14' && 'src-tauri/target/universal-apple-darwin/release/bundle/dmg/*.dmg' || 'src-tauri/target/release/bundle/msi/*.msi' }}"
 | 
			
		||||
          name: updater-test
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  publish-apps-release:
 | 
			
		||||
    permissions:
 | 
			
		||||
      contents: write
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										151
									
								
								.github/workflows/playwright.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										151
									
								
								.github/workflows/playwright.yml
									
									
									
									
										vendored
									
									
								
							@ -83,6 +83,20 @@ jobs:
 | 
			
		||||
      uses: Swatinem/rust-cache@v2
 | 
			
		||||
      with:
 | 
			
		||||
        workspaces: './src/wasm-lib'
 | 
			
		||||
    - name: Install vector
 | 
			
		||||
      run: |
 | 
			
		||||
        curl --proto '=https' --tlsv1.2 -sSfL https://sh.vector.dev > /tmp/vector.sh
 | 
			
		||||
        chmod +x /tmp/vector.sh
 | 
			
		||||
        /tmp/vector.sh -y -no-modify-path
 | 
			
		||||
        mkdir -p /tmp/vector
 | 
			
		||||
        cp .github/workflows/vector.toml /tmp/vector.toml
 | 
			
		||||
        sed -i "s#GITHUB_WORKFLOW#${GITHUB_WORKFLOW}#g" /tmp/vector.toml
 | 
			
		||||
        sed -i "s#GITHUB_REPOSITORY#${GITHUB_REPOSITORY}#g" /tmp/vector.toml
 | 
			
		||||
        sed -i "s#GITHUB_SHA#${GITHUB_SHA}#g" /tmp/vector.toml
 | 
			
		||||
        sed -i "s#GITHUB_REF_NAME#${GITHUB_REF_NAME}#g" /tmp/vector.toml
 | 
			
		||||
        sed -i "s#GH_ACTIONS_AXIOM_TOKEN#${{secrets.GH_ACTIONS_AXIOM_TOKEN}}#g" /tmp/vector.toml
 | 
			
		||||
        cat /tmp/vector.toml
 | 
			
		||||
        ${HOME}/.vector/bin/vector --config /tmp/vector.toml &
 | 
			
		||||
    - name: Build Wasm (because rust diff)
 | 
			
		||||
      if: needs.check-rust-changes.outputs.rust-changed == 'true'
 | 
			
		||||
      run: yarn build:wasm
 | 
			
		||||
@ -139,27 +153,60 @@ jobs:
 | 
			
		||||
      with:
 | 
			
		||||
        name: test-results-ubuntu-${{ github.sha }}
 | 
			
		||||
        path: test-results/
 | 
			
		||||
    - name: Run ubuntu/chrome flow retry failures
 | 
			
		||||
    - name: Run ubuntu/chrome flow (with retries)
 | 
			
		||||
      id: retry
 | 
			
		||||
      if: always()
 | 
			
		||||
      run: |
 | 
			
		||||
        if [[ -d "test-results" ]];
 | 
			
		||||
        then if [[ $(ls -1 "test-results" | wc -l) != "0" ]];
 | 
			
		||||
          then echo "retried=true" >> $GITHUB_OUTPUT;
 | 
			
		||||
          else echo "retried=false" >> $GITHUB_OUTPUT; exit 0;
 | 
			
		||||
          fi;
 | 
			
		||||
        else echo "retried=false" >> $GITHUB_OUTPUT; exit 0;
 | 
			
		||||
        fi;
 | 
			
		||||
        yarn playwright test --project="Google Chrome" --last-failed e2e/playwright/flow-tests.spec.ts
 | 
			
		||||
      env:
 | 
			
		||||
        CI: true
 | 
			
		||||
        token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
 | 
			
		||||
    - name: Run ubuntu/chrome flow
 | 
			
		||||
      if: steps.retry.outputs.retried == 'false'
 | 
			
		||||
      run: yarn playwright test --project="Google Chrome" e2e/playwright/flow-tests.spec.ts
 | 
			
		||||
        if [[ ! -f "test-results/.last-run.json" ]]; then
 | 
			
		||||
            # if no last run artifact, than run plawright normally
 | 
			
		||||
            echo "run playwright normally"
 | 
			
		||||
            yarn playwright test --project="Google Chrome" e2e/playwright/flow-tests.spec.ts || true
 | 
			
		||||
            # # send to axiom
 | 
			
		||||
            node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1
 | 
			
		||||
        fi
 | 
			
		||||
        
 | 
			
		||||
        retry=1
 | 
			
		||||
        max_retrys=4
 | 
			
		||||
        
 | 
			
		||||
        # retry failed tests, doing our own retries because using inbuilt playwright retries causes connection issues
 | 
			
		||||
        while [[ $retry -le $max_retrys ]]; do
 | 
			
		||||
            if [[ -f "test-results/.last-run.json" ]]; then
 | 
			
		||||
                failed_tests=$(jq '.failedTests | length' test-results/.last-run.json)
 | 
			
		||||
                if [[ $failed_tests -gt 0 ]]; then
 | 
			
		||||
                    echo "retried=true" >>$GITHUB_OUTPUT
 | 
			
		||||
                    echo "run playwright with last failed tests and retry $retry"
 | 
			
		||||
                    yarn playwright test --project="Google Chrome" --last-failed e2e/playwright/flow-tests.spec.ts || true
 | 
			
		||||
                    # send to axiom
 | 
			
		||||
                    node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1
 | 
			
		||||
                    retry=$((retry + 1))
 | 
			
		||||
                else
 | 
			
		||||
                    echo "retried=false" >>$GITHUB_OUTPUT
 | 
			
		||||
                    exit 0
 | 
			
		||||
                fi
 | 
			
		||||
            else
 | 
			
		||||
                echo "retried=false" >>$GITHUB_OUTPUT
 | 
			
		||||
                exit 0
 | 
			
		||||
            fi
 | 
			
		||||
        done
 | 
			
		||||
        
 | 
			
		||||
        echo "retried=false" >>$GITHUB_OUTPUT
 | 
			
		||||
        
 | 
			
		||||
        if [[ -f "test-results/.last-run.json" ]]; then
 | 
			
		||||
            failed_tests=$(jq '.failedTests | length' test-results/.last-run.json)
 | 
			
		||||
            if [[ $failed_tests -gt 0 ]]; then
 | 
			
		||||
                # if it still fails after 3 retrys, then fail the job
 | 
			
		||||
                exit 1
 | 
			
		||||
            fi
 | 
			
		||||
        fi
 | 
			
		||||
        exit 0
 | 
			
		||||
      env:
 | 
			
		||||
        CI: true
 | 
			
		||||
        token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
 | 
			
		||||
    - name: send to axiom
 | 
			
		||||
      if: always()
 | 
			
		||||
      shell: bash
 | 
			
		||||
      run: |
 | 
			
		||||
        node playwrightProcess.mjs | tee /tmp/github-actions.log
 | 
			
		||||
    - uses: actions/upload-artifact@v4
 | 
			
		||||
      if: always()
 | 
			
		||||
      with:
 | 
			
		||||
@ -226,6 +273,20 @@ jobs:
 | 
			
		||||
      uses: Swatinem/rust-cache@v2
 | 
			
		||||
      with:
 | 
			
		||||
        workspaces: './src/wasm-lib'
 | 
			
		||||
    - name: Install vector
 | 
			
		||||
      run: |
 | 
			
		||||
        curl --proto '=https' --tlsv1.2 -sSfL https://sh.vector.dev > /tmp/vector.sh
 | 
			
		||||
        chmod +x /tmp/vector.sh
 | 
			
		||||
        /tmp/vector.sh -y -no-modify-path
 | 
			
		||||
        mkdir -p /tmp/vector
 | 
			
		||||
        cp .github/workflows/vector.toml /tmp/vector.toml
 | 
			
		||||
        sed -i "" "s#GITHUB_WORKFLOW#${GITHUB_WORKFLOW}#g" /tmp/vector.toml
 | 
			
		||||
        sed -i "" "s#GITHUB_REPOSITORY#${GITHUB_REPOSITORY}#g" /tmp/vector.toml
 | 
			
		||||
        sed -i "" "s#GITHUB_SHA#${GITHUB_SHA}#g" /tmp/vector.toml
 | 
			
		||||
        sed -i "" "s#GITHUB_REF_NAME#${GITHUB_REF_NAME}#g" /tmp/vector.toml
 | 
			
		||||
        sed -i "" "s#GH_ACTIONS_AXIOM_TOKEN#${{secrets.GH_ACTIONS_AXIOM_TOKEN}}#g" /tmp/vector.toml
 | 
			
		||||
        cat /tmp/vector.toml
 | 
			
		||||
        ${HOME}/.vector/bin/vector --config /tmp/vector.toml &
 | 
			
		||||
    - name: Build Wasm (because rust diff)
 | 
			
		||||
      if: needs.check-rust-changes.outputs.rust-changed == 'true'
 | 
			
		||||
      run: yarn build:wasm
 | 
			
		||||
@ -241,26 +302,52 @@ jobs:
 | 
			
		||||
      with:
 | 
			
		||||
        name: test-results-macos-${{ github.sha }}
 | 
			
		||||
        path: test-results/
 | 
			
		||||
    - name: Run macos/safari flow retry failures
 | 
			
		||||
    - name: Run macos/safari flow (with retries)
 | 
			
		||||
      id: retry
 | 
			
		||||
      if: always()
 | 
			
		||||
      run: |
 | 
			
		||||
        if [[ -d "test-results" ]];
 | 
			
		||||
        then if [[ $(ls -1 "test-results" | wc -l) != "0" ]];
 | 
			
		||||
          then echo "retried=true" >> $GITHUB_OUTPUT;
 | 
			
		||||
          else echo "retried=false" >> $GITHUB_OUTPUT; exit 0;
 | 
			
		||||
          fi;
 | 
			
		||||
        else echo "retried=false" >> $GITHUB_OUTPUT; exit 0;
 | 
			
		||||
        fi;
 | 
			
		||||
        yarn playwright test --project="webkit" --last-failed e2e/playwright/flow-tests.spec.ts
 | 
			
		||||
      env:
 | 
			
		||||
        CI: true
 | 
			
		||||
        token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
 | 
			
		||||
    - name: Run macos/safari flow
 | 
			
		||||
      if: steps.retry.outputs.retried == 'false'
 | 
			
		||||
      # webkit doesn't work on Ubuntu because of the same reason tauri doesn't (webRTC issues)
 | 
			
		||||
      # TODO remove this and the matrix and run all tests on ubuntu when this is fixed
 | 
			
		||||
      run: yarn playwright test --project="webkit" e2e/playwright/flow-tests.spec.ts
 | 
			
		||||
        if [[ ! -f "test-results/.last-run.json" ]]; then
 | 
			
		||||
            # if no last run artifact, than run plawright normally
 | 
			
		||||
            echo "run playwright normally"
 | 
			
		||||
            yarn playwright test --project="webkit" e2e/playwright/flow-tests.spec.ts || true
 | 
			
		||||
            # # send to axiom
 | 
			
		||||
            node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1
 | 
			
		||||
        fi
 | 
			
		||||
        
 | 
			
		||||
        retry=1
 | 
			
		||||
        max_retrys=4
 | 
			
		||||
        
 | 
			
		||||
        # retry failed tests, doing our own retries because using inbuilt playwright retries causes connection issues
 | 
			
		||||
        while [[ $retry -le $max_retrys ]]; do
 | 
			
		||||
            if [[ -f "test-results/.last-run.json" ]]; then
 | 
			
		||||
                failed_tests=$(jq '.failedTests | length' test-results/.last-run.json)
 | 
			
		||||
                if [[ $failed_tests -gt 0 ]]; then
 | 
			
		||||
                    echo "retried=true" >>$GITHUB_OUTPUT
 | 
			
		||||
                    echo "run playwright with last failed tests and retry $retry"
 | 
			
		||||
                    yarn playwright test --project="webkit" --last-failed e2e/playwright/flow-tests.spec.ts || true
 | 
			
		||||
                    # send to axiom
 | 
			
		||||
                    node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1
 | 
			
		||||
                    retry=$((retry + 1))
 | 
			
		||||
                else
 | 
			
		||||
                    echo "retried=false" >>$GITHUB_OUTPUT
 | 
			
		||||
                    exit 0
 | 
			
		||||
                fi
 | 
			
		||||
            else
 | 
			
		||||
                echo "retried=false" >>$GITHUB_OUTPUT
 | 
			
		||||
                exit 0
 | 
			
		||||
            fi
 | 
			
		||||
        done
 | 
			
		||||
        
 | 
			
		||||
        echo "retried=false" >>$GITHUB_OUTPUT
 | 
			
		||||
        
 | 
			
		||||
        if [[ -f "test-results/.last-run.json" ]]; then
 | 
			
		||||
            failed_tests=$(jq '.failedTests | length' test-results/.last-run.json)
 | 
			
		||||
            if [[ $failed_tests -gt 0 ]]; then
 | 
			
		||||
                # if it still fails after 3 retrys, then fail the job
 | 
			
		||||
                exit 1
 | 
			
		||||
            fi
 | 
			
		||||
        fi
 | 
			
		||||
        exit 0
 | 
			
		||||
      env:
 | 
			
		||||
        CI: true
 | 
			
		||||
        token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
 | 
			
		||||
 | 
			
		||||
@ -2458,6 +2458,44 @@ test.describe('Onboarding tests', () => {
 | 
			
		||||
    await expect(onboardingOverlayLocator).toBeVisible()
 | 
			
		||||
    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', () => {
 | 
			
		||||
@ -4563,6 +4601,53 @@ test.describe('Sketch tests', () => {
 | 
			
		||||
      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 }) => {
 | 
			
		||||
    // this was a regression https://github.com/KittyCAD/modeling-app/issues/2832
 | 
			
		||||
    await page.addInitScript(async () => {
 | 
			
		||||
 | 
			
		||||
@ -20,7 +20,10 @@ export default defineConfig({
 | 
			
		||||
  /* Different amount of parallelism on CI and local. */
 | 
			
		||||
  workers: process.env.CI ? 4 : 4,
 | 
			
		||||
  /* Reporter to use. See https://playwright.dev/docs/test-reporters */
 | 
			
		||||
  reporter: 'html',
 | 
			
		||||
  reporter: [
 | 
			
		||||
    [process.env.CI ? 'dot' : 'list'],
 | 
			
		||||
    ['json', { outputFile: './test-results/report.json' }],
 | 
			
		||||
  ],
 | 
			
		||||
  /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
 | 
			
		||||
  use: {
 | 
			
		||||
    /* Base URL to use in actions like `await page.goto('/')`. */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										65
									
								
								playwrightProcess.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								playwrightProcess.mjs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,65 @@
 | 
			
		||||
import { readFileSync } from 'fs'
 | 
			
		||||
 | 
			
		||||
const data = readFileSync('./test-results/report.json', 'utf8')
 | 
			
		||||
 | 
			
		||||
// types, but was easier to store and run as normal js
 | 
			
		||||
// interface FailedTest {
 | 
			
		||||
//     name: string;
 | 
			
		||||
//     projectName: string;
 | 
			
		||||
//     error: string;
 | 
			
		||||
// }
 | 
			
		||||
 | 
			
		||||
// interface Spec {
 | 
			
		||||
//     title: string;
 | 
			
		||||
//     tests: Test[];
 | 
			
		||||
// }
 | 
			
		||||
 | 
			
		||||
// interface Test {
 | 
			
		||||
//     expectedStatus: 'passed' | 'failed' | 'pending';
 | 
			
		||||
//     projectName: string;
 | 
			
		||||
//     title: string;
 | 
			
		||||
//     results: {
 | 
			
		||||
//         status: 'passed' | 'failed' | 'pending';
 | 
			
		||||
//         error: {stack: string}
 | 
			
		||||
//     }[]
 | 
			
		||||
// }
 | 
			
		||||
 | 
			
		||||
// interface Suite {
 | 
			
		||||
//     title: string
 | 
			
		||||
//     suites: Suite[];
 | 
			
		||||
//     specs: Spec[];
 | 
			
		||||
// }
 | 
			
		||||
 | 
			
		||||
// const processReport = (suites: Suite[]): FailedTest[] => {
 | 
			
		||||
//     const failedTests: FailedTest[] = []
 | 
			
		||||
//     const loopSuites = (suites: Suite[], previousName = '') => {
 | 
			
		||||
const processReport = (suites) => {
 | 
			
		||||
  const failedTests = []
 | 
			
		||||
  const loopSuites = (suites, previousName = '') => {
 | 
			
		||||
    if (!suites) return
 | 
			
		||||
    for (const suite of suites) {
 | 
			
		||||
      const name = (previousName ? `${previousName} -- ` : '') + suite.title
 | 
			
		||||
      for (const spec of suite.specs) {
 | 
			
		||||
        for (const test of spec.tests) {
 | 
			
		||||
          for (const result of test.results) {
 | 
			
		||||
            if ((result.status !== 'passed') && test.expectedStatus === 'passed') {
 | 
			
		||||
              failedTests.push({
 | 
			
		||||
                name: (name + ' -- ' + spec.title) + (test.title ? ` -- ${test.title}` : ''),
 | 
			
		||||
                status: result.status,
 | 
			
		||||
                projectName: test.projectName,
 | 
			
		||||
                error: result.error?.stack,
 | 
			
		||||
              })
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      loopSuites(suite.suites, name)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  loopSuites(suites)
 | 
			
		||||
  return failedTests.map(line => JSON.stringify(line)).join('\n')
 | 
			
		||||
}
 | 
			
		||||
const failedTests = processReport(JSON.parse(data).suites)
 | 
			
		||||
// log to stdout to be piped to axiom
 | 
			
		||||
console.log(failedTests)
 | 
			
		||||
 | 
			
		||||
@ -518,9 +518,9 @@ export class CameraControls {
 | 
			
		||||
    direction.normalize()
 | 
			
		||||
    this.camera.position.copy(this.target).addScaledVector(direction, distance)
 | 
			
		||||
  }
 | 
			
		||||
  usePerspectiveCamera = async () => {
 | 
			
		||||
  usePerspectiveCamera = async (forceSend = false) => {
 | 
			
		||||
    this._usePerspectiveCamera()
 | 
			
		||||
    if (this.syncDirection === 'clientToEngine') {
 | 
			
		||||
    if (forceSend || this.syncDirection === 'clientToEngine') {
 | 
			
		||||
      await this.engineCommandManager.sendSceneCommand({
 | 
			
		||||
        type: 'modeling_cmd_req',
 | 
			
		||||
        cmd_id: uuidv4(),
 | 
			
		||||
 | 
			
		||||
@ -717,7 +717,7 @@ export const CamDebugSettings = () => {
 | 
			
		||||
          if (camSettings.type === 'perspective') {
 | 
			
		||||
            sceneInfra.camControls.useOrthographicCamera()
 | 
			
		||||
          } else {
 | 
			
		||||
            sceneInfra.camControls.usePerspectiveCamera()
 | 
			
		||||
            sceneInfra.camControls.usePerspectiveCamera(true)
 | 
			
		||||
          }
 | 
			
		||||
        }}
 | 
			
		||||
      />
 | 
			
		||||
 | 
			
		||||
@ -35,6 +35,7 @@ import {
 | 
			
		||||
  canExtrudeSelection,
 | 
			
		||||
  handleSelectionBatch,
 | 
			
		||||
  isSelectionLastLine,
 | 
			
		||||
  isRangeInbetweenCharacters,
 | 
			
		||||
  isSketchPipe,
 | 
			
		||||
  updateSelections,
 | 
			
		||||
} from 'lib/selections'
 | 
			
		||||
@ -425,6 +426,7 @@ export const ModelingMachineProvider = ({
 | 
			
		||||
 | 
			
		||||
          if (
 | 
			
		||||
            selectionRanges.codeBasedSelections.length === 0 ||
 | 
			
		||||
            isRangeInbetweenCharacters(selectionRanges) ||
 | 
			
		||||
            isSelectionLastLine(selectionRanges, codeManager.code)
 | 
			
		||||
          ) {
 | 
			
		||||
            // they have no selection, we should enable the button
 | 
			
		||||
 | 
			
		||||
@ -360,6 +360,14 @@ export function isSelectionLastLine(
 | 
			
		||||
  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 = {
 | 
			
		||||
  selection: Selection
 | 
			
		||||
  ast: Program
 | 
			
		||||
 | 
			
		||||
@ -126,11 +126,17 @@ async function getUser(context: UserContext) {
 | 
			
		||||
  if (!token && isTauri()) return Promise.reject(new Error('No token found'))
 | 
			
		||||
  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 {
 | 
			
		||||
      user: LOCAL_USER,
 | 
			
		||||
      token,
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const userPromise = !isTauri()
 | 
			
		||||
    ? fetch(url, {
 | 
			
		||||
@ -144,6 +150,11 @@ async function getUser(context: UserContext) {
 | 
			
		||||
 | 
			
		||||
  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))
 | 
			
		||||
 | 
			
		||||
  return {
 | 
			
		||||
 | 
			
		||||
@ -2,13 +2,18 @@ import { OnboardingButtons, useDismiss, useNextClick } from '.'
 | 
			
		||||
import { onboardingPaths } from 'routes/Onboarding/paths'
 | 
			
		||||
import { useEffect, useState } from 'react'
 | 
			
		||||
import { useModelingContext } from 'hooks/useModelingContext'
 | 
			
		||||
import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
 | 
			
		||||
 | 
			
		||||
export default function UserMenu() {
 | 
			
		||||
  const { context } = useModelingContext()
 | 
			
		||||
  const { auth } = useSettingsAuthContext()
 | 
			
		||||
  const dismiss = useDismiss()
 | 
			
		||||
  const next = useNextClick(onboardingPaths.PROJECT_MENU)
 | 
			
		||||
  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,
 | 
			
		||||
  // so the onboarding text can be updated if it fails to load.
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user