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:
Pierre Jacquier
2024-01-04 04:54:07 -05:00
committed by GitHub
parent 82905caad6
commit c999819450
7 changed files with 76 additions and 16 deletions

View File

@ -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')
}) })

View File

@ -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: [

View File

@ -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>

View File

@ -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>

View File

@ -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

View File

@ -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">

View File

@ -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>
</> </>