Rename desktop e2e scripts and tags for consistency (#7240)

* Rename desktop e2e scripts and tags for consistency

* Show local command in main test step

* Restore 'e2e' prefix to clarify GitHub UI

* Add web script to contributor guide
This commit is contained in:
Jace Browning
2025-05-29 09:29:03 -04:00
committed by GitHub
parent b123dacc41
commit 55e1ec7dad
24 changed files with 129 additions and 118 deletions

View File

@ -7,11 +7,11 @@ if [[ ! -f "test-results/.last-run.json" ]]; then
# If no last run artifact, than run Playwright normally
echo "run playwright normally"
if [[ "$3" == *ubuntu* ]]; then
xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- npm run test:playwright:electron -- --shard=$1/$2 || true
xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- npm run test:e2e:desktop -- --shard=$1/$2 || true
elif [[ "$3" == *windows* ]]; then
npm run test:playwright:electron -- --grep=@windows --shard=$1/$2 || true
npm run test:e2e:desktop -- --grep=@windows --shard=$1/$2 || true
elif [[ "$3" == *macos* ]]; then
npm run test:playwright:electron -- --grep=@macos --shard=$1/$2 || true
npm run test:e2e:desktop -- --grep=@macos --shard=$1/$2 || true
else
echo "Do not run Playwright. Unable to detect os runtime."
exit 1
@ -31,11 +31,11 @@ while [[ $retry -le $max_retries ]]; do
echo "retried=true" >>$GITHUB_OUTPUT
echo "run playwright with last failed tests and retry $retry"
if [[ "$3" == *ubuntu* ]]; then
xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- npm run test:playwright:electron -- --last-failed || true
xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- npm run test:e2e:desktop -- --last-failed || true
elif [[ "$3" == *windows* ]]; then
npm run test:playwright:electron -- --grep=@windows --last-failed || true
npm run test:e2e:desktop -- --grep=@windows --last-failed || true
elif [[ "$3" == *macos* ]]; then
npm run test:playwright:electron -- --grep=@macos --last-failed || true
npm run test:e2e:desktop -- --grep=@macos --last-failed || true
else
echo "Do not run playwright. Unable to detect os runtime."
exit 1

View File

@ -20,9 +20,11 @@ permissions:
jobs:
prepare-wasm:
# separate job on Ubuntu to build or fetch the wasm blob once on the fastest runner
runs-on: runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64
steps:
- uses: actions/checkout@v4
- id: filter
@ -103,9 +105,10 @@ jobs:
needs: [prepare-wasm]
runs-on: runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64
name: playwright:snapshots:ubuntu
name: e2e:snapshots
steps:
- uses: actions/create-github-app-token@v1
id: app-token
with:
@ -135,7 +138,7 @@ jobs:
- name: Install dependencies
run: npm install
- name: Cache browsers
- name: Download browser cache
uses: actions/cache@v4
with:
path: |
@ -145,7 +148,7 @@ jobs:
- name: Install browsers
run: npm run playwright install --with-deps
- name: Test snapshots
- name: npm run test:snapshots
uses: nick-fields/retry@v3.0.2
with:
shell: bash
@ -216,6 +219,7 @@ jobs:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}
name: e2e:web (${{ contains(matrix.os, 'ubuntu') && 'ubuntu' || (contains(matrix.os, 'windows') && 'windows' || 'macos') }})
env:
OS_NAME: ${{ contains(matrix.os, 'ubuntu') && 'ubuntu' || (contains(matrix.os, 'windows') && 'windows' || 'macos') }}
@ -250,7 +254,7 @@ jobs:
- name: Install dependencies
run: npm install
- name: Cache browsers
- name: Download browser cache
uses: actions/cache@v4
with:
path: |
@ -267,7 +271,7 @@ jobs:
GH_ACTIONS_AXIOM_TOKEN: ${{ secrets.GH_ACTIONS_AXIOM_TOKEN }}
OS_NAME: ${{ env.OS_NAME }}
- name: Test web
- name: npm run test:e2e:web
uses: nick-fields/retry@v3.0.2
with:
shell: bash
@ -336,7 +340,7 @@ jobs:
shardIndex: 2
shardTotal: 2
runs-on: ${{ matrix.os }}
name: playwright:electron:${{ contains(matrix.os, 'ubuntu') && 'ubuntu' || (contains(matrix.os, 'windows') && 'windows' || 'macos') }} (shard ${{ matrix.shardIndex }})
name: e2e:desktop (${{ contains(matrix.os, 'ubuntu') && 'ubuntu' || (contains(matrix.os, 'windows') && 'windows' || 'macos') }}, shard ${{ matrix.shardIndex }})
env:
OS_NAME: ${{ contains(matrix.os, 'ubuntu') && 'ubuntu' || (contains(matrix.os, 'windows') && 'windows' || 'macos') }}
@ -346,7 +350,7 @@ jobs:
- uses: actions/download-artifact@v4
name: prepared-wasm
- name: Copy prepared wasm
- name: Copy prepared Wasm
run: |
ls -R prepared-wasm
cp prepared-wasm/kcl_wasm_lib_bg.wasm public
@ -362,7 +366,7 @@ jobs:
id: deps-install
run: npm install
- name: Cache browsers
- name: Download browser cache
uses: actions/cache@v4
with:
path: |
@ -372,9 +376,6 @@ jobs:
- name: Install browsers
run: npm run playwright install --with-deps
- name: Build web
run: npm run tronb:vite:dev
- name: Start Vector
if: ${{ !contains(matrix.os, 'windows') }}
run: .github/ci-cd-scripts/start-vector-${{ env.OS_NAME }}.sh
@ -382,6 +383,9 @@ jobs:
GH_ACTIONS_AXIOM_TOKEN: ${{ secrets.GH_ACTIONS_AXIOM_TOKEN }}
OS_NAME: ${{ env.OS_NAME }}
- name: Build app
run: npm run tronb:vite:dev
- uses: actions/download-artifact@v4
if: ${{ !cancelled() && (success() || failure()) }}
continue-on-error: true
@ -389,7 +393,7 @@ jobs:
name: test-results-${{ env.OS_NAME }}-${{ matrix.shardIndex }}-${{ github.sha }}
path: test-results/
- name: Run playwright/electron flow (with retries)
- name: npm run test:e2e:desktop
id: retry
if: ${{ !cancelled() && steps.deps-install.outcome == 'success' }}
uses: nick-fields/retry@v3.0.2

View File

@ -213,14 +213,21 @@ npm run test:snapshots
```
You may use `-- --update-snapshots` as needed.
#### Electron flow tests (Chromium on Ubuntu, macOS, Windows)
#### Desktop tests (Electron on all platforms)
```
npm run playwright -- install chromium
npm run test:playwright:electron:local
npm run test:e2e:desktop:local
```
You may use `-- -g "my test"` to match specific test titles, or `-- path/to/file.spec.ts` for a test file.
#### Web tests (Google Chrome on all platforms)
```
npm run test:e2e:web
```
#### Debugger
However, if you want a debugger I recommend using VSCode and the `playwright` extension, as the above command is a cruder debugger that steps into every function call which is annoying.

View File

@ -129,9 +129,9 @@ endif
.PHONY: test-e2e-desktop
test-e2e-desktop: install build ## Run the desktop e2e tests
ifdef E2E_GREP
npm run test:playwright:electron -- --grep="$(E2E_GREP)" --max-failures=$(E2E_FAILURES)
npm run test:e2e:desktop -- --grep="$(E2E_GREP)" --max-failures=$(E2E_FAILURES)
else
npm run test:playwright:electron -- --workers='100%'
npm run test:e2e:desktop -- --workers='100%'
endif
###############################################################################

View File

@ -5,7 +5,7 @@ import * as fsp from 'fs/promises'
test.describe('Electron app header tests', () => {
test(
'Open Command Palette button has correct shortcut',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ page }, testInfo) => {
await page.setBodyDimensions({ width: 1200, height: 500 })
@ -30,7 +30,7 @@ test.describe('Electron app header tests', () => {
test(
'User settings has correct shortcut',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ page, toolbar }, testInfo) => {
await page.setBodyDimensions({ width: 1200, height: 500 })

View File

@ -4,7 +4,7 @@ import { expect, test } from '@e2e/playwright/zoo-test'
test.describe('Authentication tests', () => {
test(
`The user can sign out and back in`,
{ tag: ['@electron'] },
{ tag: ['@desktop'] },
async ({ page, homePage, signInPage, toolbar, tronApp }) => {
if (!tronApp) {
fail()

View File

@ -275,7 +275,7 @@ middle()`)
test(
'Opening multiple panes persists when switching projects',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
// Setup multiple projects.
await context.folderSetupFn(async (dir) => {
@ -346,7 +346,7 @@ test(
test(
'external change of file contents are reflected in editor',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
const PROJECT_DIR_NAME = 'lee-was-here'
const { dir: projectsDir } = await context.folderSetupFn(async (dir) => {

View File

@ -10,7 +10,7 @@ import { expect, test } from '@e2e/playwright/zoo-test'
test(
'export works on the first try',
{ tag: ['@electron', '@macos', '@windows', '@skipLocalEngine'] },
{ tag: ['@desktop', '@macos', '@windows', '@skipLocalEngine'] },
async ({ page, context, scene, tronApp, cmdBar }, testInfo) => {
if (!tronApp) {
fail()

View File

@ -1337,7 +1337,7 @@ sketch001 = startSketchOn(XZ)
test(
`Can import a local OBJ file`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ page, context }, testInfo) => {
await context.folderSetupFn(async (dir) => {
const bracketDir = join(dir, 'cube')

View File

@ -57,7 +57,7 @@ sketch003 = startSketchOn(plane001)
test.describe('Feature Tree pane', () => {
test(
'User can go to definition and go to function definition',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, homePage, scene, editor, toolbar, cmdBar, page }) => {
await context.folderSetupFn(async (dir) => {
const bracketDir = join(dir, 'test-sample')
@ -150,7 +150,7 @@ test.describe('Feature Tree pane', () => {
test(
`User can edit sketch (but not on offset plane yet) from the feature tree`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, homePage, scene, editor, toolbar, page }) => {
await context.addInitScript((initialCode) => {
localStorage.setItem('persistCode', initialCode)

View File

@ -13,7 +13,7 @@ import { expect, test } from '@e2e/playwright/zoo-test'
test.describe('integrations tests', () => {
test(
'Creating a new file or switching file while in sketchMode should exit sketchMode',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ page, context, homePage, scene, editor, toolbar, cmdBar }) => {
await context.folderSetupFn(async (dir) => {
const bracketDir = join(dir, 'test-sample')
@ -100,7 +100,7 @@ test.describe('when using the file tree to', () => {
test(
`rename ${fromFile} to ${toFile}, and doesn't crash on reload and settings load`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ page }, testInfo) => {
const { panesOpen, pasteCodeInEditor, renameFile, editorTextMatches } =
await getUtils(page, test)
@ -142,7 +142,7 @@ test.describe('when using the file tree to', () => {
test(
`create many new files of the same name, incrementing their names`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ page }, testInfo) => {
const { panesOpen, createNewFile } = await getUtils(page, test)
@ -174,7 +174,7 @@ test.describe('when using the file tree to', () => {
test(
'create a new file with the same name as an existing file cancels the operation',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page, homePage, scene, editor, toolbar }, testInfo) => {
const projectName = 'cube'
const mainFile = 'main.kcl'
@ -240,7 +240,7 @@ test.describe('when using the file tree to', () => {
test(
`create new folders and that doesn't trigger a navigation`,
{ tag: ['@electron', '@macos', '@windows'] },
{ tag: ['@desktop', '@macos', '@windows'] },
async ({ page, homePage, scene, toolbar, cmdBar }) => {
await homePage.goToModelingScene()
await scene.settled(cmdBar)
@ -260,7 +260,7 @@ test.describe('when using the file tree to', () => {
test(
'deleting all files recreates a default main.kcl with no code',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ page }, testInfo) => {
const { panesOpen, pasteCodeInEditor, deleteFile, editorTextMatches } =
await getUtils(page, test)
@ -291,7 +291,7 @@ test.describe('when using the file tree to', () => {
test(
'loading small file, then large, then back to small',
{
tag: '@electron',
tag: '@desktop',
},
async ({ page }, testInfo) => {
const {
@ -361,7 +361,7 @@ test.describe('when using the file tree to', () => {
test.describe('Renaming in the file tree', () => {
test(
'A file you have open',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
const { dir } = await context.folderSetupFn(async (dir) => {
await fsp.mkdir(join(dir, 'Test Project'), { recursive: true })
@ -450,7 +450,7 @@ test.describe('Renaming in the file tree', () => {
test(
'A file you do not have open',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
const { dir } = await context.folderSetupFn(async (dir) => {
await fsp.mkdir(join(dir, 'Test Project'), { recursive: true })
@ -536,7 +536,7 @@ test.describe('Renaming in the file tree', () => {
test(
`A folder you're not inside`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
const { dir } = await context.folderSetupFn(async (dir) => {
await fsp.mkdir(join(dir, 'Test Project'), { recursive: true })
@ -618,7 +618,7 @@ test.describe('Renaming in the file tree', () => {
test(
`A folder you are inside`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ page, context }, testInfo) => {
const { dir } = await context.folderSetupFn(async (dir) => {
await fsp.mkdir(join(dir, 'Test Project'), { recursive: true })
@ -721,7 +721,7 @@ test.describe('Renaming in the file tree', () => {
test.describe('Deleting items from the file pane', () => {
test(
`delete file when main.kcl exists, navigate to main.kcl`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ page, context }, testInfo) => {
await context.folderSetupFn(async (dir) => {
const testDir = join(dir, 'testProject')
@ -786,7 +786,7 @@ test.describe('Deleting items from the file pane', () => {
test(
`Delete folder we are not in, don't navigate`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
await context.folderSetupFn(async (dir) => {
await fsp.mkdir(join(dir, 'Test Project'), { recursive: true })
@ -840,7 +840,7 @@ test.describe('Deleting items from the file pane', () => {
test(
`Delete folder we are in, navigate to main.kcl`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
await context.folderSetupFn(async (dir) => {
await fsp.mkdir(join(dir, 'Test Project'), { recursive: true })
@ -906,7 +906,7 @@ test.describe('Deleting items from the file pane', () => {
// Copied from tests above.
test(
`external deletion of project navigates back home`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
const TEST_PROJECT_NAME = 'Test Project'
const { dir: projectsDirName } = await context.folderSetupFn(
@ -970,7 +970,7 @@ test.describe('Deleting items from the file pane', () => {
// Similar to the above
test(
`external deletion of file in sub-directory updates the file tree and recreates it on code editor typing`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
const TEST_PROJECT_NAME = 'Test Project'
const { dir: projectsDirName } = await context.folderSetupFn(
@ -1045,7 +1045,7 @@ test.describe('Deleting items from the file pane', () => {
test.describe('Undo and redo do not keep history when navigating between files', () => {
test(
`open a file, change something, open a different file, hitting undo should do nothing`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
await context.folderSetupFn(async (dir) => {
const testDir = join(dir, 'testProject')
@ -1112,7 +1112,7 @@ test.describe('Undo and redo do not keep history when navigating between files',
test(
`open a file, change something, undo it, open a different file, hitting redo should do nothing`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
await context.folderSetupFn(async (dir) => {
const testDir = join(dir, 'testProject')
@ -1212,7 +1212,7 @@ test.describe('Undo and redo do not keep history when navigating between files',
test(
`cloned file has an incremented name and same contents`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ page, context, homePage }, testInfo) => {
const { panesOpen, cloneFile } = await getUtils(page, test)

View File

@ -5,7 +5,7 @@ import * as fsp from 'fs/promises'
test.describe('Import UI tests', () => {
test(
'shows toast when trying to sketch on imported face, and hovering over imported geometry should NOT highlight any code',
{ tag: ['@electron', '@macos', '@windows'] },
{ tag: ['@desktop', '@macos', '@windows'] },
async ({ context, page, homePage, toolbar, scene, editor, cmdBar }) => {
await context.folderSetupFn(async (dir) => {
const projectDir = path.join(dir, 'import-test')

View File

@ -6,7 +6,7 @@ import { expect, test } from '@e2e/playwright/zoo-test'
test(
'When machine-api server not found butt is disabled and shows the reason',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page, scene, cmdBar }, testInfo) => {
await context.folderSetupFn(async (dir) => {
const bracketDir = join(dir, 'bracket')
@ -43,7 +43,7 @@ test(
test(
'When machine-api server not found home screen & project status shows the reason',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page, scene, cmdBar }, testInfo) => {
await context.folderSetupFn(async (dir) => {
const bracketDir = join(dir, 'bracket')

View File

@ -13,7 +13,7 @@ import { expect, test } from '@e2e/playwright/zoo-test'
*/
test.describe(
'Native file menu',
{ tag: ['@electron', '@macos', '@windows'] },
{ tag: ['@desktop', '@macos', '@windows'] },
() => {
test('Home page', async ({ tronApp, cmdBar, page, homePage }) => {
if (!tronApp) fail()

View File

@ -43,7 +43,7 @@ async function insertPartIntoAssembly(
test.describe('Point-and-click assemblies tests', () => {
test(
`Insert kcl parts into assembly as whole module import`,
{ tag: ['@electron', '@macos', '@windows'] },
{ tag: ['@desktop', '@macos', '@windows'] },
async ({
context,
page,
@ -188,7 +188,7 @@ test.describe('Point-and-click assemblies tests', () => {
await page.waitForTimeout(10000)
await editor.expectEditor.toContain(
`
import "nested/twice/main.kcl" as main
import "nested/twice/main.kcl" as main
`,
{ shouldNormalise: true }
)
@ -198,7 +198,7 @@ test.describe('Point-and-click assemblies tests', () => {
test(
`Can still translate, rotate, and delete inserted parts even with non standard code`,
{ tag: ['@electron', '@macos', '@windows'] },
{ tag: ['@desktop', '@macos', '@windows'] },
async ({
context,
page,
@ -394,7 +394,7 @@ test.describe('Point-and-click assemblies tests', () => {
test(
`Insert the bracket part into an assembly and transform it`,
{ tag: ['@electron', '@macos', '@windows'] },
{ tag: ['@desktop', '@macos', '@windows'] },
async ({
context,
page,
@ -585,7 +585,7 @@ test.describe('Point-and-click assemblies tests', () => {
test(
`Insert foreign parts into assembly and delete them`,
{ tag: ['@electron', '@macos', '@windows'] },
{ tag: ['@desktop', '@macos', '@windows'] },
async ({
context,
page,
@ -736,7 +736,7 @@ test.describe('Point-and-click assemblies tests', () => {
test(
'Assembly gets reexecuted when imported models are updated externally',
{ tag: ['@electron', '@macos', '@windows'] },
{ tag: ['@desktop', '@macos', '@windows'] },
async ({ context, page, homePage, scene, toolbar, cmdBar, tronApp }) => {
if (!tronApp) {
fail()
@ -826,7 +826,7 @@ foreign
test(
`Point-and-click clone`,
{ tag: ['@electron', '@macos', '@windows'] },
{ tag: ['@desktop', '@macos', '@windows'] },
async ({
context,
page,

View File

@ -17,7 +17,7 @@ import { expect, test } from '@e2e/playwright/zoo-test'
test(
'projects reload if a new one is created, deleted, or renamed externally',
{ tag: ['@electron', '@macos', '@windows'] },
{ tag: ['@desktop', '@macos', '@windows'] },
async ({ context, page }, testInfo) => {
let externalCreatedProjectName = 'external-created-project'
@ -63,7 +63,7 @@ test(
test(
'click help/keybindings from home page',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ page }, testInfo) => {
await page.setBodyDimensions({ width: 1200, height: 500 })
@ -81,7 +81,7 @@ test(
test(
'click help/keybindings from project page',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ scene, cmdBar, context, page }, testInfo) => {
await context.folderSetupFn(async (dir) => {
const bracketDir = path.join(dir, 'bracket')
@ -112,7 +112,7 @@ test(
test(
'open a file in a project works and renders, open another file in different project with errors, it should clear the scene',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ scene, cmdBar, context, page, editor }, testInfo) => {
await context.folderSetupFn(async (dir) => {
const bracketDir = path.join(dir, 'bracket')
@ -184,7 +184,7 @@ test(
test(
'open a file in a project works and renders, open another file in different project that is empty, it should clear the scene',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ scene, cmdBar, context, page }, testInfo) => {
await context.folderSetupFn(async (dir) => {
const bracketDir = path.join(dir, 'bracket')
@ -244,7 +244,7 @@ test(
test(
'open a file in a project works and renders, open empty file, it should clear the scene',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
await context.folderSetupFn(async (dir) => {
const bracketDir = path.join(dir, 'bracket')
@ -310,7 +310,7 @@ test(
test(
'open a file in a project works and renders, open another file in the same project with errors, it should clear the scene',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ scene, cmdBar, context, page }, testInfo) => {
await context.folderSetupFn(async (dir) => {
const bracketDir = path.join(dir, 'bracket')
@ -382,7 +382,7 @@ test(
test(
'when code with error first loads you get errors in console',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page, editor }, testInfo) => {
await context.folderSetupFn(async (dir) => {
await fsp.mkdir(path.join(dir, 'broken-code'), { recursive: true })
@ -416,7 +416,7 @@ test.describe('Can export from electron app', () => {
for (const method of exportMethods) {
test(
`Can export using ${method}`,
{ tag: ['@electron', '@skipLocalEngine'] },
{ tag: ['@desktop', '@skipLocalEngine'] },
async ({ scene, cmdBar, context, page, tronApp }, testInfo) => {
if (!tronApp) {
fail()
@ -507,7 +507,7 @@ test.describe('Can export from electron app', () => {
})
test(
'Rename and delete projects, also spam arrow keys when renaming',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
await context.folderSetupFn(async (dir) => {
await fsp.mkdir(`${dir}/router-template-slate`, { recursive: true })
@ -723,7 +723,7 @@ test(
test(
'pressing "delete" on home screen should do nothing',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page, homePage }, testInfo) => {
await context.folderSetupFn(async (dir) => {
await fsp.mkdir(`${dir}/router-template-slate`, { recursive: true })
@ -753,7 +753,7 @@ test(
test.describe(`Project management commands`, () => {
test(
`Rename from project page`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page, scene, cmdBar }, testInfo) => {
const projectName = `my_project_to_rename`
await context.folderSetupFn(async (dir) => {
@ -815,7 +815,7 @@ test.describe(`Project management commands`, () => {
test(
`Delete from project page`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page, scene, cmdBar }, testInfo) => {
const projectName = `my_project_to_delete`
await context.folderSetupFn(async (dir) => {
@ -869,7 +869,7 @@ test.describe(`Project management commands`, () => {
)
test(
`Rename from home page`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page, homePage, scene, cmdBar }, testInfo) => {
const projectName = `my_project_to_rename`
await context.folderSetupFn(async (dir) => {
@ -927,7 +927,7 @@ test.describe(`Project management commands`, () => {
)
test(
`Delete from home page`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page, scene, cmdBar }, testInfo) => {
const projectName = `my_project_to_delete`
await context.folderSetupFn(async (dir) => {
@ -1103,7 +1103,7 @@ test(`Create a few projects using the default project name`, async ({
test(
'File in the file pane should open with a single click',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, homePage, page }, testInfo) => {
const projectName = 'router-template-slate'
await context.folderSetupFn(async (dir) => {
@ -1145,7 +1145,7 @@ test(
test(
'Nested directories in project without main.kcl do not create main.kcl',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ scene, cmdBar, context, page }, testInfo) => {
let testDir: string | undefined
await context.folderSetupFn(async (dir) => {
@ -1202,7 +1202,7 @@ test(
test(
'Deleting projects, can delete individual project, can still create projects after deleting all',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
const projectData = [
['router-template-slate', 'cylinder.kcl'],
@ -1280,7 +1280,7 @@ test(
test(
'Can load a file with CRLF line endings',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page, scene, cmdBar }, testInfo) => {
await context.folderSetupFn(async (dir) => {
const routerTemplateDir = path.join(dir, 'router-template-slate')
@ -1312,7 +1312,7 @@ test(
test(
'Can sort projects on home page',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
const projectData = [
['router-template-slate', 'cylinder.kcl'],
@ -1419,7 +1419,7 @@ test(
test(
'When the project folder is empty, user can create new project and open it.',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ page }, testInfo) => {
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 })
@ -1515,7 +1515,7 @@ extrude001 = extrude(sketch001, length = 200)`)
test(
'Opening a project should successfully load the stream, (regression test that this also works when switching between projects)',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page, cmdBar, homePage, scene }, testInfo) => {
await context.folderSetupFn(async (dir) => {
await fsp.mkdir(path.join(dir, 'router-template-slate'), {
@ -1628,7 +1628,7 @@ test(
test(
'You can change the root projects directory and nothing is lost',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page, tronApp, homePage }, testInfo) => {
if (!tronApp) {
fail()
@ -1735,7 +1735,7 @@ test(
test(
'Search projects on desktop home',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
const projectData = [
['basic bracket', 'focusrite_scarlett_mounting_bracket.kcl'],
@ -1791,7 +1791,7 @@ test(
test(
'file pane is scrollable when there are many files',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ scene, cmdBar, context, page }, testInfo) => {
await context.folderSetupFn(async (dir) => {
const testDir = path.join(dir, 'testProject')
@ -1892,7 +1892,7 @@ test(
test(
'select all in code editor does not actually select all, just what is visible (regression)',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
await context.folderSetupFn(async (dir) => {
// rust/kcl-lib/e2e/executor/inputs/mike_stress_test.kcl
@ -1950,7 +1950,7 @@ test(
test(
'Settings persist across restarts',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ page, toolbar }, testInfo) => {
await test.step('We can change a user setting like theme', async () => {
await page.setBodyDimensions({ width: 1200, height: 500 })
@ -1982,7 +1982,7 @@ test(
test(
'Original project name persist after onboarding',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ page, toolbar }, testInfo) => {
const nextButton = page.getByTestId('onboarding-next')
await page.setBodyDimensions({ width: 1200, height: 500 })
@ -2022,7 +2022,7 @@ test(
test(
'project name with foreign characters should open',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
await context.folderSetupFn(async (dir) => {
const bracketDir = path.join(dir, 'العربية')
@ -2067,7 +2067,7 @@ test(
test(
'import from nested directory',
{ tag: ['@electron', '@windows', '@macos'] },
{ tag: ['@desktop', '@windows', '@macos'] },
async ({ scene, cmdBar, context, page }) => {
await context.folderSetupFn(async (dir) => {
const bracketDir = path.join(dir, 'bracket')

View File

@ -63,7 +63,7 @@ test.describe('edit with AI example snapshots', () => {
test(
`change colour`,
// TODO this is more of a snapshot, but atm it needs to be manually run locally to update the files
{ tag: ['@electron'] },
{ tag: ['@desktop'] },
async ({ context, homePage, cmdBar, editor, page, scene }) => {
const project = 'test-dir'
await context.folderSetupFn(async (dir) => {

View File

@ -558,7 +558,7 @@ extrude002 = extrude(profile002, length = 150)
test(
`Network health indicator only appears in modeling view`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }) => {
await context.folderSetupFn(async (dir) => {
const bracketDir = path.join(dir, 'bracket')

View File

@ -279,7 +279,7 @@ profile001 = startProfile(sketch001, at = [12.34, -12.34])
test(
'Paused stream freezes view frame, unpause reconnect is seamless to user',
{ tag: ['@electron', '@skipLocalEngine'] },
{ tag: ['@desktop', '@skipLocalEngine'] },
async ({ page, homePage, scene, cmdBar, toolbar, tronApp }) => {
const networkToggle = page.getByTestId('network-toggle')
const networkToggleConnectedText = page.getByText('Connected')

View File

@ -1120,7 +1120,7 @@ part002 = startSketchOn(XZ)
test.describe('Electron constraint tests', () => {
test(
'Able to double click label to set constraint',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ page, context, homePage, scene, editor, toolbar, cmdBar }) => {
await context.folderSetupFn(async (dir) => {
const bracketDir = path.join(dir, 'test-sample')

View File

@ -84,7 +84,7 @@ test.describe('Testing loading external models', () => {
*/
test(
'Desktop: should create new file by default, creates a second file with automatic unique name',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ editor, context, page, scene, cmdBar, toolbar }) => {
if (runningOnWindows()) {
}
@ -196,7 +196,7 @@ test.describe('Testing loading external models', () => {
externalModelCases.map(({ modelName, deconflictedModelName, modelPath }) => {
test(
`Load external models from local drive - ${modelName}`,
{ tag: ['@electron'] },
{ tag: ['@desktop'] },
async ({ page, homePage, scene, toolbar, cmdBar, tronApp }) => {
if (!tronApp) {
fail()

View File

@ -278,7 +278,7 @@ test.describe(
test(
`Project settings override user settings on desktop`,
{ tag: ['@electron'] },
{ tag: ['@desktop'] },
async ({ context, page }, testInfo) => {
const projectName = 'bracket'
const { dir: projectDirName } = await context.folderSetupFn(
@ -373,7 +373,7 @@ test.describe(
test(
`Load desktop app with no settings file`,
{
tag: '@electron',
tag: '@desktop',
},
async ({ page }, testInfo) => {
await page.setBodyDimensions({ width: 1200, height: 500 })
@ -393,7 +393,7 @@ test.describe(
test(
`Load desktop app with a settings file, but no project directory setting`,
{
tag: '@electron',
tag: '@desktop',
},
async ({ context, page, tronApp }, testInfo) => {
if (!tronApp) {
@ -425,7 +425,7 @@ test.describe(
test(
'user settings reload on external change, on project and modeling view',
{
tag: '@electron',
tag: '@desktop',
},
async ({ context, page, tronApp }, testInfo) => {
if (!tronApp) {
@ -486,7 +486,7 @@ test.describe(
test(
'project settings reload on external change',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
const { dir: projectDirName } = await context.folderSetupFn(
async () => {}
@ -536,7 +536,7 @@ test.describe(
test(
`Closing settings modal should go back to the original file being viewed`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
await context.folderSetupFn(async (dir) => {
const bracketDir = join(dir, 'project-000')

View File

@ -640,7 +640,7 @@ test.describe('Mocked Text-to-CAD API tests', { tag: ['@skipWin'] }, () => {
test(
'Home Page -> Text To CAD -> New Project -> Stay in home page -> Reject -> Project should be deleted',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
const projectName = 'my-project-name'
const prompt = '2x2x2 cube'
@ -678,7 +678,7 @@ test.describe('Mocked Text-to-CAD API tests', { tag: ['@skipWin'] }, () => {
test(
'Home Page -> Text To CAD -> New Project -> Stay in home page -> Accept -> should navigate to file',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
const u = await getUtils(page)
const projectName = 'my-project-name'
@ -724,7 +724,7 @@ test.describe('Mocked Text-to-CAD API tests', { tag: ['@skipWin'] }, () => {
test(
'Home Page -> Text To CAD -> Existing Project -> Stay in home page -> Reject -> should delete single file',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ homePage, page }, testInfo) => {
const projectName = 'my-project-name'
const prompt = '2x2x2 cube'
@ -767,7 +767,7 @@ test.describe('Mocked Text-to-CAD API tests', { tag: ['@skipWin'] }, () => {
test(
'Home Page -> Text To CAD -> Existing Project -> Stay in home page -> Accept -> should navigate to file',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ homePage, page }, testInfo) => {
const u = await getUtils(page)
const projectName = 'my-project-name'
@ -818,7 +818,7 @@ test.describe('Mocked Text-to-CAD API tests', { tag: ['@skipWin'] }, () => {
test(
'Home Page -> Text To CAD -> New Project -> Navigate to the project -> Reject -> should go to home page',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ homePage, page }, testInfo) => {
const projectName = 'my-project-name'
const prompt = '2x2x2 cube'
@ -864,7 +864,7 @@ test.describe('Mocked Text-to-CAD API tests', { tag: ['@skipWin'] }, () => {
test(
'Home Page -> Text To CAD -> New Project -> Navigate to the project -> Accept -> should stay in same file',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ homePage, page }, testInfo) => {
const projectName = 'my-project-name'
const prompt = '2x2x2 cube'
@ -907,7 +907,7 @@ test.describe('Mocked Text-to-CAD API tests', { tag: ['@skipWin'] }, () => {
test(
'Home Page -> Text To CAD -> Existing Project -> Navigate to the project -> Reject -> should load main.kcl',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ homePage, page }, testInfo) => {
const u = await getUtils(page)
const projectName = 'my-project-name'
@ -962,7 +962,7 @@ test.describe('Mocked Text-to-CAD API tests', { tag: ['@skipWin'] }, () => {
test(
'Home Page -> Text To CAD -> Existing Project -> Navigate to the project -> Accept -> should load 2x2x2-cube.kcl',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ homePage, page }, testInfo) => {
const u = await getUtils(page)
const projectName = 'my-project-name'
@ -1019,7 +1019,7 @@ test.describe('Mocked Text-to-CAD API tests', { tag: ['@skipWin'] }, () => {
test(
'Home Page -> Text To CAD -> New Project -> Navigate to different project -> Reject -> should stay in project',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ homePage, page }, testInfo) => {
const u = await getUtils(page)
const projectName = 'my-project-name'
@ -1096,7 +1096,7 @@ test.describe('Mocked Text-to-CAD API tests', { tag: ['@skipWin'] }, () => {
test(
'Home Page -> Text To CAD -> New Project -> Navigate to different project -> Accept -> should go to new project',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ page, homePage }, testInfo) => {
const u = await getUtils(page)
const projectName = 'my-project-name'
@ -1165,7 +1165,7 @@ test.describe('Mocked Text-to-CAD API tests', { tag: ['@skipWin'] }, () => {
test(
'Home Page -> Text To CAD -> Existing Project -> Navigate to different project -> Reject -> should stay in same project',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ page, homePage }, testInfo) => {
const u = await getUtils(page)
const projectName = 'my-project-name'
@ -1240,7 +1240,7 @@ test.describe('Mocked Text-to-CAD API tests', { tag: ['@skipWin'] }, () => {
test(
'Home Page -> Text To CAD -> Existing Project -> Navigate to different project -> Accept -> should navigate to new project',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ page, homePage }, testInfo) => {
const u = await getUtils(page)
const projectName = 'my-project-name'

View File

@ -133,9 +133,9 @@
"test:unit": "vitest run --mode development --exclude **/jest-component-unit-tests/*",
"test:unit:components": "jest -c jest-component-unit-tests/jest.config.ts --rootDir jest-component-unit-tests/",
"test:e2e:web": "cross-env TARGET=web NODE_ENV=development playwright test --config=playwright.config.ts --project=\"Google Chrome\" --grep=@web",
"test:playwright:electron": "playwright test --config=playwright.electron.config.ts --grep-invert=@snapshot",
"test:playwright:electron:local": "npm run tronb:vite:dev && playwright test --config=playwright.electron.config.ts --grep-invert=@snapshot --grep-invert=\"$(curl --silent https://test-analysis-bot.hawk-dinosaur.ts.net/projects/KittyCAD/modeling-app/tests/disabled/regex)\"",
"test:playwright:electron:local-engine": "npm run tronb:vite:dev && playwright test --config=playwright.electron.config.ts --grep-invert='@snapshot|@skipLocalEngine' --grep-invert=\"$(curl --silent https://test-analysis-bot.hawk-dinosaur.ts.net/projects/KittyCAD/modeling-app/tests/disabled/regex)\"",
"test:e2e:desktop": "cross-env TARGET=desktop playwright test --config=playwright.electron.config.ts --grep-invert=@snapshot",
"test:e2e:desktop:local": "cross-env TARGET=desktop npm run tronb:vite:dev && playwright test --config=playwright.electron.config.ts --grep-invert=@snapshot --grep-invert=\"$(curl --silent https://test-analysis-bot.hawk-dinosaur.ts.net/projects/KittyCAD/modeling-app/tests/disabled/regex)\"",
"test:e2e:desktop:local-engine": "cross-env TARGET=desktop npm run tronb:vite:dev && playwright test --config=playwright.electron.config.ts --grep-invert='@snapshot|@skipLocalEngine' --grep-invert=\"$(curl --silent https://test-analysis-bot.hawk-dinosaur.ts.net/projects/KittyCAD/modeling-app/tests/disabled/regex)\"",
"test:unit:local": "npm run simpleserver:bg && npm run test:unit; kill-port 3000"
},
"browserslist": {