Get existing tauri e2e tests to work on Windows (#2394)
* WIP: Get existing tauri e2e tests to work on Windows
Will fix #2393
* Enable windows stage (will fail)
* WIP msedge version sync
* Move setup edge before build
* Manual debug build (no action)
* Specify v119 for npm package
* Fixes on auth test
* Working test on win10
* Clean up
* Disable yarn cache to help debug the mismatch issue
* Revert "Disable yarn cache to help debug the mismatch issue"
This reverts commit e6abc7db42
.
* Explicit webviewOptions and remove tauri driver fork
* Double \\ workaround for windows
* Clean up
* Clean up and readme
* Quick fix
* Lint
* Clippy fix
* Back to tauri-action and disable windows CI tests for early merge
* Back to 10sec delay
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* Timer reset
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* Trigger CI
* Back to 1 pw worker
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
13
.github/workflows/ci.yml
vendored
13
.github/workflows/ci.yml
vendored
@ -364,6 +364,19 @@ jobs:
|
|||||||
E2E_APPLICATION: "./src-tauri/target/${{ env.BUILD_RELEASE == 'true' && 'release' || 'debug' }}/zoo-modeling-app"
|
E2E_APPLICATION: "./src-tauri/target/${{ env.BUILD_RELEASE == 'true' && 'release' || 'debug' }}/zoo-modeling-app"
|
||||||
KITTYCAD_API_TOKEN: ${{ env.BUILD_RELEASE == 'true' && secrets.KITTYCAD_API_TOKEN || secrets.KITTYCAD_API_TOKEN_DEV }}
|
KITTYCAD_API_TOKEN: ${{ env.BUILD_RELEASE == 'true' && secrets.KITTYCAD_API_TOKEN || secrets.KITTYCAD_API_TOKEN_DEV }}
|
||||||
|
|
||||||
|
- name: Run e2e tests (windows only)
|
||||||
|
# TODO: enable CI tests once the mismatch issue is addressed
|
||||||
|
# if: ${{ matrix.os == 'windows-latest' && github.event_name != 'release' && github.event_name != 'schedule' }}
|
||||||
|
if: false
|
||||||
|
run: |
|
||||||
|
cargo install tauri-driver --force
|
||||||
|
yarn wdio run wdio.conf.ts
|
||||||
|
env:
|
||||||
|
E2E_APPLICATION: ".\\src-tauri\\target\\${{ env.BUILD_RELEASE == 'true' && 'release' || 'debug' }}\\Zoo Modeling App.exe"
|
||||||
|
KITTYCAD_API_TOKEN: ${{ env.BUILD_RELEASE == 'true' && secrets.KITTYCAD_API_TOKEN || secrets.KITTYCAD_API_TOKEN_DEV }}
|
||||||
|
VITE_KC_API_BASE_URL: ${{ env.BUILD_RELEASE == 'true' && 'https://api.zoo.dev' || 'https://api.dev.zoo.dev' }}
|
||||||
|
E2E_TAURI_ENABLED: true
|
||||||
|
TS_NODE_COMPILER_OPTIONS: '{"module": "commonjs"}'
|
||||||
|
|
||||||
publish-apps-release:
|
publish-apps-release:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
19
README.md
19
README.md
@ -309,6 +309,25 @@ PS: for the debug panel, the following JSON is useful for snapping the camera
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
### Tauri e2e tests
|
||||||
|
|
||||||
|
#### Windows (local only until the CI edge version mismatch is fixed)
|
||||||
|
|
||||||
|
```
|
||||||
|
yarn install
|
||||||
|
yarn build:wasm
|
||||||
|
cp src/wasm-lib/pkg/wasm_lib_bg.wasm public
|
||||||
|
yarn vite build --mode development
|
||||||
|
yarn tauri build --debug -b
|
||||||
|
$env:KITTYCAD_API_TOKEN="<YOUR_KITTYCAD_API_TOKEN>"
|
||||||
|
$env:VITE_KC_API_BASE_URL="https://api.dev.zoo.dev"
|
||||||
|
$env:E2E_TAURI_ENABLED="true"
|
||||||
|
$env:TS_NODE_COMPILER_OPTIONS='{"module": "commonjs"}'
|
||||||
|
$env:E2E_APPLICATION=".\src-tauri\target\debug\Zoo Modeling App.exe"
|
||||||
|
Stop-Process -Name msedgedriver
|
||||||
|
yarn wdio run wdio.conf.ts
|
||||||
|
```
|
||||||
|
|
||||||
## KCL
|
## KCL
|
||||||
|
|
||||||
For how to contribute to KCL, [see our KCL README](https://github.com/KittyCAD/modeling-app/tree/main/src/wasm-lib/kcl).
|
For how to contribute to KCL, [see our KCL README](https://github.com/KittyCAD/modeling-app/tree/main/src/wasm-lib/kcl).
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 41 KiB |
Binary file not shown.
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
@ -1,11 +1,19 @@
|
|||||||
import { browser, $, expect } from '@wdio/globals'
|
import { browser, $, expect } from '@wdio/globals'
|
||||||
import fs from 'fs/promises'
|
import fs from 'fs/promises'
|
||||||
|
import path from 'path'
|
||||||
|
import os from 'os'
|
||||||
|
|
||||||
const documentsDir = `${process.env.HOME}/Documents`
|
const isWin32 = os.platform() === 'win32'
|
||||||
const userSettingsDir = `${process.env.HOME}/.config/dev.zoo.modeling-app`
|
const documentsDir = path.join(os.homedir(), 'Documents')
|
||||||
const defaultProjectDir = `${documentsDir}/zoo-modeling-app-projects`
|
const userSettingsDir = path.join(
|
||||||
const newProjectDir = `${documentsDir}/a-different-directory`
|
os.homedir(),
|
||||||
const userCodeDir = '/tmp/kittycad_user_code'
|
'.config',
|
||||||
|
'dev.zoo.modeling-app'
|
||||||
|
)
|
||||||
|
const defaultProjectDir = path.join(documentsDir, 'zoo-modeling-app-projects')
|
||||||
|
const newProjectDir = path.join(documentsDir, 'a-different-directory')
|
||||||
|
const tmp = process.env.TEMP || '/tmp'
|
||||||
|
const userCodeDir = path.join(tmp, 'kittycad_user_code')
|
||||||
|
|
||||||
async function click(element: WebdriverIO.Element): Promise<void> {
|
async function click(element: WebdriverIO.Element): Promise<void> {
|
||||||
// Workaround for .click(), see https://github.com/tauri-apps/tauri/issues/6541
|
// Workaround for .click(), see https://github.com/tauri-apps/tauri/issues/6541
|
||||||
@ -24,7 +32,7 @@ async function setDatasetValue(
|
|||||||
await browser.execute(`arguments[0].dataset.${property} = "${value}"`, field)
|
await browser.execute(`arguments[0].dataset.${property} = "${value}"`, field)
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('ZMA (Tauri, Linux)', () => {
|
describe('ZMA (Tauri)', () => {
|
||||||
it('opens the auth page and signs in', async () => {
|
it('opens the auth page and signs in', async () => {
|
||||||
// Clean up filesystem from previous tests
|
// Clean up filesystem from previous tests
|
||||||
await new Promise((resolve) => setTimeout(resolve, 100))
|
await new Promise((resolve) => setTimeout(resolve, 100))
|
||||||
@ -42,9 +50,7 @@ describe('ZMA (Tauri, Linux)', () => {
|
|||||||
await new Promise((resolve) => setTimeout(resolve, 2000))
|
await new Promise((resolve) => setTimeout(resolve, 2000))
|
||||||
|
|
||||||
// Get from main.rs
|
// Get from main.rs
|
||||||
const userCode = await (
|
const userCode = await (await fs.readFile(userCodeDir)).toString()
|
||||||
await fs.readFile('/tmp/kittycad_user_code')
|
|
||||||
).toString()
|
|
||||||
console.log(`Found user code ${userCode}`)
|
console.log(`Found user code ${userCode}`)
|
||||||
|
|
||||||
// Device flow: verify
|
// Device flow: verify
|
||||||
@ -92,7 +98,12 @@ describe('ZMA (Tauri, Linux)', () => {
|
|||||||
* to be able to skip the folder selection dialog if data-testValue
|
* to be able to skip the folder selection dialog if data-testValue
|
||||||
* has a value, allowing us to test the input otherwise works.
|
* has a value, allowing us to test the input otherwise works.
|
||||||
*/
|
*/
|
||||||
await setDatasetValue(projectDirInput, 'testValue', newProjectDir)
|
// TODO: understand why we need to force double \ on Windows
|
||||||
|
await setDatasetValue(
|
||||||
|
projectDirInput,
|
||||||
|
'testValue',
|
||||||
|
isWin32 ? newProjectDir.replaceAll('\\', '\\\\') : newProjectDir
|
||||||
|
)
|
||||||
const projectDirButton = await $('[data-testid="project-directory-button"]')
|
const projectDirButton = await $('[data-testid="project-directory-button"]')
|
||||||
await click(projectDirButton)
|
await click(projectDirButton)
|
||||||
await new Promise((resolve) => setTimeout(resolve, 500))
|
await new Promise((resolve) => setTimeout(resolve, 500))
|
||||||
@ -102,6 +113,15 @@ describe('ZMA (Tauri, Linux)', () => {
|
|||||||
const nameInput = await $('[data-testid="projects-defaultProjectName"]')
|
const nameInput = await $('[data-testid="projects-defaultProjectName"]')
|
||||||
expect(await nameInput.getValue()).toEqual('project-$nnn')
|
expect(await nameInput.getValue()).toEqual('project-$nnn')
|
||||||
|
|
||||||
|
// Setting it back (for back to back local tests)
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 5000))
|
||||||
|
await setDatasetValue(
|
||||||
|
projectDirInput,
|
||||||
|
'testValue',
|
||||||
|
isWin32 ? defaultProjectDir.replaceAll('\\', '\\\\') : newProjectDir
|
||||||
|
)
|
||||||
|
await click(projectDirButton)
|
||||||
|
|
||||||
const closeButton = await $('[data-testid="settings-close-button"]')
|
const closeButton = await $('[data-testid="settings-close-button"]')
|
||||||
await click(closeButton)
|
await click(closeButton)
|
||||||
})
|
})
|
||||||
@ -120,9 +140,15 @@ describe('ZMA (Tauri, Linux)', () => {
|
|||||||
it('opens the new file and expects a loading stream', async () => {
|
it('opens the new file and expects a loading stream', async () => {
|
||||||
const projectLink = await $('[data-testid="project-link"]')
|
const projectLink = await $('[data-testid="project-link"]')
|
||||||
await click(projectLink)
|
await click(projectLink)
|
||||||
const errorText = await $('[data-testid="unexpected-error"]')
|
if (isWin32) {
|
||||||
expect(await errorText.getText()).toContain('unexpected error')
|
// TODO: actually do something to check that the stream is up
|
||||||
await browser.execute('window.location.href = "tauri://localhost/home"')
|
await new Promise((resolve) => setTimeout(resolve, 5000))
|
||||||
|
} else {
|
||||||
|
const errorText = await $('[data-testid="unexpected-error"]')
|
||||||
|
expect(await errorText.getText()).toContain('unexpected error')
|
||||||
|
}
|
||||||
|
const base = isWin32 ? 'http://tauri.localhost' : 'tauri://localhost'
|
||||||
|
await browser.execute(`window.location.href = "${base}/home"`)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('signs out', async () => {
|
it('signs out', async () => {
|
||||||
|
@ -267,7 +267,15 @@ async fn login(app: tauri::AppHandle, host: &str) -> Result<String, InvokeError>
|
|||||||
let e2e_tauri_enabled = env::var("E2E_TAURI_ENABLED").is_ok();
|
let e2e_tauri_enabled = env::var("E2E_TAURI_ENABLED").is_ok();
|
||||||
if e2e_tauri_enabled {
|
if e2e_tauri_enabled {
|
||||||
log::warn!("E2E_TAURI_ENABLED is set, won't open {} externally", auth_uri.secret());
|
log::warn!("E2E_TAURI_ENABLED is set, won't open {} externally", auth_uri.secret());
|
||||||
tokio::fs::write("/tmp/kittycad_user_code", details.user_code().secret())
|
let mut temp = String::from("/tmp");
|
||||||
|
// Overwrite with Windows variable
|
||||||
|
match env::var("TEMP") {
|
||||||
|
Ok(val) => temp = val,
|
||||||
|
Err(_e) => println!("Fallback to default /tmp"),
|
||||||
|
}
|
||||||
|
let path = Path::new(&temp).join("kittycad_user_code");
|
||||||
|
println!("Writing to {}", path.to_string_lossy());
|
||||||
|
tokio::fs::write(path, details.user_code().secret())
|
||||||
.await
|
.await
|
||||||
.map_err(|e| InvokeError::from_anyhow(e.into()))?;
|
.map_err(|e| InvokeError::from_anyhow(e.into()))?;
|
||||||
} else {
|
} else {
|
||||||
|
@ -8,6 +8,7 @@ const application =
|
|||||||
process.env.E2E_APPLICATION || `./src-tauri/target/release/zoo-modeling-app`
|
process.env.E2E_APPLICATION || `./src-tauri/target/release/zoo-modeling-app`
|
||||||
|
|
||||||
export const config = {
|
export const config = {
|
||||||
|
hostname: '127.0.0.1',
|
||||||
port: 4444,
|
port: 4444,
|
||||||
specs: ['./e2e/tauri/specs/**/*.ts'],
|
specs: ['./e2e/tauri/specs/**/*.ts'],
|
||||||
maxInstances: 1,
|
maxInstances: 1,
|
||||||
@ -16,6 +17,7 @@ export const config = {
|
|||||||
maxInstances: 1,
|
maxInstances: 1,
|
||||||
'tauri:options': {
|
'tauri:options': {
|
||||||
application,
|
application,
|
||||||
|
webviewOptions: {}, // Windows only
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
Reference in New Issue
Block a user