Tauri e2e coverage: check filesystem settings, create/open file (#1191)
* Create a file and expect stream to fail on Linux
Fixes #1190
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* Try to add @franknoirot's suggestion
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* Check settings first
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* Working test
* Clean up
* Linux fix
* Linux fix attempt #2
* BUILD_RELEASE true temporarily
* Revert "BUILD_RELEASE true temporarily"
This reverts commit 42b2d5f6bb
.
* Better comment
* Home checks, and proj name check
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* Open proj
* Fix defaultDir in test
* WIP signout
* Workaround to recover from error
* Typo
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
@ -1,19 +1,26 @@
|
|||||||
import { browser, $, expect } from '@wdio/globals'
|
import { browser, $, expect } from '@wdio/globals'
|
||||||
import fs from 'fs/promises'
|
import fs from 'fs/promises'
|
||||||
|
|
||||||
describe('KCMA (Tauri, Linux)', () => {
|
const defaultDir = `${process.env.HOME}/Documents/zoo-modeling-app-projects`
|
||||||
it('opens the auth page, signs in, and signs out', async () => {
|
const userCodeDir = '/tmp/kittycad_user_code'
|
||||||
// Clean up previous tests
|
|
||||||
|
async function click(element: WebdriverIO.Element): Promise<void> {
|
||||||
|
// Workaround for .click(), see https://github.com/tauri-apps/tauri/issues/6541
|
||||||
|
await element.waitForClickable()
|
||||||
|
await browser.execute('arguments[0].click();', element)
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('ZMA (Tauri, Linux)', () => {
|
||||||
|
it('opens the auth page and signs in', async () => {
|
||||||
|
// Clean up filesystem from previous tests
|
||||||
await new Promise((resolve) => setTimeout(resolve, 100))
|
await new Promise((resolve) => setTimeout(resolve, 100))
|
||||||
await fs.rm('/tmp/kittycad_user_code', { force: true })
|
await fs.rm(defaultDir, { force: true, recursive: true })
|
||||||
await browser.execute('window.localStorage.clear()')
|
await fs.rm(userCodeDir, { force: true })
|
||||||
|
|
||||||
const signInButton = await $('[data-testid="sign-in-button"]')
|
const signInButton = await $('[data-testid="sign-in-button"]')
|
||||||
expect(await signInButton.getText()).toEqual('Sign in')
|
expect(await signInButton.getText()).toEqual('Sign in')
|
||||||
|
|
||||||
// Workaround for .click(), see https://github.com/tauri-apps/tauri/issues/6541
|
await click(signInButton)
|
||||||
await signInButton.waitForClickable()
|
|
||||||
await browser.execute('arguments[0].click();', signInButton)
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 2000))
|
await new Promise((resolve) => setTimeout(resolve, 2000))
|
||||||
|
|
||||||
// Get from main.rs
|
// Get from main.rs
|
||||||
@ -49,14 +56,51 @@ describe('KCMA (Tauri, Linux)', () => {
|
|||||||
// Now should be signed in
|
// Now should be signed in
|
||||||
const newFileButton = await $('[data-testid="home-new-file"]')
|
const newFileButton = await $('[data-testid="home-new-file"]')
|
||||||
expect(await newFileButton.getText()).toEqual('New file')
|
expect(await newFileButton.getText()).toEqual('New file')
|
||||||
|
})
|
||||||
|
|
||||||
// So let's sign out!
|
it('opens the settings page, checks filesystem settings, and closes the settings page', async () => {
|
||||||
const menuButton = await $('[data-testid="user-sidebar-toggle"]')
|
const menuButton = await $('[data-testid="user-sidebar-toggle"]')
|
||||||
await menuButton.waitForClickable()
|
await click(menuButton)
|
||||||
await browser.execute('arguments[0].click();', menuButton)
|
|
||||||
|
const settingsButton = await $('[data-testid="settings-button"]')
|
||||||
|
await click(settingsButton)
|
||||||
|
|
||||||
|
const defaultDirInput = await $('[data-testid="default-directory-input"]')
|
||||||
|
expect(await defaultDirInput.getValue()).toEqual(defaultDir)
|
||||||
|
|
||||||
|
const nameInput = await $('[data-testid="name-input"]')
|
||||||
|
expect(await nameInput.getValue()).toEqual('project-$nnn')
|
||||||
|
|
||||||
|
const closeButton = await $('[data-testid="close-button"]')
|
||||||
|
await click(closeButton)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('checks that no file exists, creates a new file', async () => {
|
||||||
|
const homeSection = await $('[data-testid="home-section"]')
|
||||||
|
expect(await homeSection.getText()).toContain('No Projects found')
|
||||||
|
|
||||||
|
const newFileButton = await $('[data-testid="home-new-file"]')
|
||||||
|
await click(newFileButton)
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 1000))
|
||||||
|
|
||||||
|
expect(await homeSection.getText()).toContain('project-000')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('opens the new file and expects an error on Linux', async () => {
|
||||||
|
const projectLink = await $('[data-testid="project-link"]')
|
||||||
|
await click(projectLink)
|
||||||
|
const error = await $('h3')
|
||||||
|
expect(await error.getText()).toContain(
|
||||||
|
"Can't find variable: RTCPeerConnection"
|
||||||
|
)
|
||||||
|
await browser.execute('window.location.href = "tauri://localhost/home"')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('signs out', async () => {
|
||||||
|
const menuButton = await $('[data-testid="user-sidebar-toggle"]')
|
||||||
|
await click(menuButton)
|
||||||
const signoutButton = await $('[data-testid="user-sidebar-sign-out"]')
|
const signoutButton = await $('[data-testid="user-sidebar-sign-out"]')
|
||||||
await signoutButton.waitForClickable()
|
await click(signoutButton)
|
||||||
await browser.execute('arguments[0].click();', signoutButton)
|
|
||||||
const newSignInButton = await $('[data-testid="sign-in-button"]')
|
const newSignInButton = await $('[data-testid="sign-in-button"]')
|
||||||
expect(await newSignInButton.getText()).toEqual('Sign in')
|
expect(await newSignInButton.getText()).toEqual('Sign in')
|
||||||
})
|
})
|
||||||
|
@ -112,6 +112,7 @@ export type ProjectWithEntryPointMetadata = FileEntry & {
|
|||||||
}
|
}
|
||||||
export type HomeLoaderData = {
|
export type HomeLoaderData = {
|
||||||
projects: ProjectWithEntryPointMetadata[]
|
projects: ProjectWithEntryPointMetadata[]
|
||||||
|
newDefaultDirectory?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreateBrowserRouterArg = Parameters<typeof createBrowserRouter>[0]
|
type CreateBrowserRouterArg = Parameters<typeof createBrowserRouter>[0]
|
||||||
@ -259,6 +260,7 @@ const router = createBrowserRouter(
|
|||||||
const projectDir = await initializeProjectDirectory(
|
const projectDir = await initializeProjectDirectory(
|
||||||
persistedSettings.defaultDirectory || ''
|
persistedSettings.defaultDirectory || ''
|
||||||
)
|
)
|
||||||
|
let newDefaultDirectory: string | undefined = undefined
|
||||||
if (projectDir !== persistedSettings.defaultDirectory) {
|
if (projectDir !== persistedSettings.defaultDirectory) {
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
SETTINGS_PERSIST_KEY,
|
SETTINGS_PERSIST_KEY,
|
||||||
@ -267,6 +269,7 @@ const router = createBrowserRouter(
|
|||||||
defaultDirectory: projectDir,
|
defaultDirectory: projectDir,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
newDefaultDirectory = projectDir
|
||||||
}
|
}
|
||||||
const projectsNoMeta = (await readDir(projectDir)).filter(
|
const projectsNoMeta = (await readDir(projectDir)).filter(
|
||||||
isProjectDirectory
|
isProjectDirectory
|
||||||
@ -282,6 +285,7 @@ const router = createBrowserRouter(
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
projects,
|
projects,
|
||||||
|
newDefaultDirectory,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
|
@ -107,6 +107,7 @@ function ProjectCard({
|
|||||||
<Link
|
<Link
|
||||||
className="flex-1 text-liquid-100 after:content-[''] after:absolute after:inset-0"
|
className="flex-1 text-liquid-100 after:content-[''] after:absolute after:inset-0"
|
||||||
to={`${paths.FILE}/${encodeURIComponent(project.path)}`}
|
to={`${paths.FILE}/${encodeURIComponent(project.path)}`}
|
||||||
|
data-testid="project-link"
|
||||||
>
|
>
|
||||||
{project.name?.replace(FILE_EXT, '')}
|
{project.name?.replace(FILE_EXT, '')}
|
||||||
</Link>
|
</Link>
|
||||||
|
@ -128,6 +128,7 @@ const UserSidebarMenu = ({ user }: { user?: User }) => {
|
|||||||
: paths.HOME + paths.SETTINGS
|
: paths.HOME + paths.SETTINGS
|
||||||
navigate(targetPath)
|
navigate(targetPath)
|
||||||
}}
|
}}
|
||||||
|
data-testid="settings-button"
|
||||||
>
|
>
|
||||||
Settings
|
Settings
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
|
@ -38,7 +38,7 @@ export async function initializeProjectDirectory(directory: string) {
|
|||||||
docDirectory = await documentDir()
|
docDirectory = await documentDir()
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log('error', e)
|
console.log('error', e)
|
||||||
docDirectory = await homeDir() // seems to work better on Linux
|
docDirectory = `${await homeDir()}Documents/` // for headless Linux (eg. Github Actions)
|
||||||
}
|
}
|
||||||
|
|
||||||
const INITIAL_DEFAULT_DIR = docDirectory + PROJECT_FOLDER
|
const INITIAL_DEFAULT_DIR = docDirectory + PROJECT_FOLDER
|
||||||
|
@ -37,13 +37,20 @@ import { homeCommandBarConfig } from 'lib/commandBarConfigs/homeCommandConfig'
|
|||||||
const Home = () => {
|
const Home = () => {
|
||||||
const { commandBarSend } = useCommandsContext()
|
const { commandBarSend } = useCommandsContext()
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const { projects: loadedProjects } = useLoaderData() as HomeLoaderData
|
const { projects: loadedProjects, newDefaultDirectory } =
|
||||||
|
useLoaderData() as HomeLoaderData
|
||||||
const {
|
const {
|
||||||
settings: {
|
settings: {
|
||||||
context: { defaultDirectory, defaultProjectName },
|
context: { defaultDirectory, defaultProjectName },
|
||||||
send: sendToSettings,
|
send: sendToSettings,
|
||||||
},
|
},
|
||||||
} = useGlobalStateContext()
|
} = useGlobalStateContext()
|
||||||
|
if (newDefaultDirectory) {
|
||||||
|
sendToSettings({
|
||||||
|
type: 'Set Default Directory',
|
||||||
|
data: { defaultDirectory: newDefaultDirectory },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const [state, send] = useMachine(homeMachine, {
|
const [state, send] = useMachine(homeMachine, {
|
||||||
context: {
|
context: {
|
||||||
@ -222,7 +229,7 @@ const Home = () => {
|
|||||||
</ActionButton>
|
</ActionButton>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section>
|
<section data-testid="home-section">
|
||||||
<p className="my-4 text-sm text-chalkboard-80 dark:text-chalkboard-30">
|
<p className="my-4 text-sm text-chalkboard-80 dark:text-chalkboard-30">
|
||||||
Loaded from{' '}
|
Loaded from{' '}
|
||||||
<span className="text-energy-70 dark:text-energy-40">
|
<span className="text-energy-70 dark:text-energy-40">
|
||||||
|
@ -113,6 +113,7 @@ export const Settings = () => {
|
|||||||
'text-destroy-20 group-hover:text-destroy-10 hover:text-destroy-10',
|
'text-destroy-20 group-hover:text-destroy-10 hover:text-destroy-10',
|
||||||
}}
|
}}
|
||||||
className="hover:border-destroy-40"
|
className="hover:border-destroy-40"
|
||||||
|
data-testid="close-button"
|
||||||
>
|
>
|
||||||
Close
|
Close
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
@ -178,6 +179,7 @@ export const Settings = () => {
|
|||||||
className="flex-1 px-2 bg-transparent"
|
className="flex-1 px-2 bg-transparent"
|
||||||
value={defaultDirectory}
|
value={defaultDirectory}
|
||||||
disabled
|
disabled
|
||||||
|
data-testid="default-directory-input"
|
||||||
/>
|
/>
|
||||||
<ActionButton
|
<ActionButton
|
||||||
Element="button"
|
Element="button"
|
||||||
@ -209,6 +211,7 @@ export const Settings = () => {
|
|||||||
}}
|
}}
|
||||||
autoCapitalize="off"
|
autoCapitalize="off"
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
|
data-testid="name-input"
|
||||||
/>
|
/>
|
||||||
</SettingsSection>
|
</SettingsSection>
|
||||||
</>
|
</>
|
||||||
|
Reference in New Issue
Block a user