Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adding ui component tests #590

Merged
merged 28 commits into from
Mar 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
860f8de
docs: additional cypress + vitest comparison content
JessicaSachs Dec 21, 2021
d9d4754
feat: ui testing
edimitchel Jan 19, 2022
4150f74
fix: seperate cypress tests
edimitchel Jan 19, 2022
7a60412
Merge branch 'vitest-dev:main' into main
JessicaSachs Jan 20, 2022
6c8ec2a
feat: adding cypress component testing for ui
JessicaSachs Jan 20, 2022
205e987
chore: share the common deps for global app setup
JessicaSachs Jan 20, 2022
b78b171
Merge remote-tracking branch 'origin/main' into jess/adding-cy-compon…
JessicaSachs Jan 20, 2022
d042221
spacing
JessicaSachs Jan 20, 2022
bd26fe8
Merge remote-tracking branch 'origin/main' into jess/adding-cy-compon…
JessicaSachs Jan 22, 2022
0f0cf9f
Update package.json
JessicaSachs Jan 22, 2022
ea4c8a5
chore: adding OptimizationPersist + PkgConfig to reduce flake
JessicaSachs Jan 23, 2022
9e0ab89
Merge branch 'jess/adding-cy-component-tests' of https://github.com/J…
JessicaSachs Jan 23, 2022
343ca1f
chore: workaround for unocss hmr
JessicaSachs Jan 23, 2022
c5317d8
chore: adding ts-ignore comments
JessicaSachs Jan 23, 2022
8fb64c2
chore: reordering data-testid
JessicaSachs Jan 23, 2022
c16d457
chore: ts-expect-error
JessicaSachs Jan 23, 2022
09bdb65
--allow-empty
JessicaSachs Jan 25, 2022
8c1269f
bug: reproduction of failing vite + cypress setup
JessicaSachs Jan 27, 2022
bc8514f
chore: adding Vite 2.9.0-beta.3 to cold-start stability issues for UI…
JessicaSachs Mar 17, 2022
c378713
Merge remote-tracking branch 'origin/main' into jess/adding-cy-compon…
JessicaSachs Mar 17, 2022
9a9c9df
chore: fixing types
JessicaSachs Mar 17, 2022
70b3359
chore: fixing types
JessicaSachs Mar 17, 2022
91fa5da
reenabling tests
JessicaSachs Mar 17, 2022
09cf89e
adding faker seed back in
JessicaSachs Mar 17, 2022
939ebdb
bumping faker version
JessicaSachs Mar 17, 2022
60b136b
Merge branch 'main' into jess/adding-cy-component-tests
antfu Mar 19, 2022
c8e8d61
Merge branch 'main' into jess/adding-cy-component-tests
antfu Mar 21, 2022
170f15a
Merge branch 'main' into jess/adding-cy-component-tests
antfu Mar 21, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 20 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,23 @@ jobs:

- name: Test
run: pnpm run test:ci

test-ui:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Install pnpm
uses: pnpm/action-setup@v2.2.1

- name: Set node
uses: actions/setup-node@v2
with:
node-version: 16.x
cache: "pnpm"

- name: Install
run: pnpm i

- name: Test UI
run: pnpm run ui:test
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,8 @@ dist
.idea
.DS_Store
bench/test/*/*/
cypress/videos
cypress/downloads
cypress/screenshots
docs/public/user-avatars
docs/public/sponsors
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
"test:ci": "cross-env CI=true pnpm -r --stream --filter !@vitest/monorepo --filter !test-fails run test -- --allowOnly",
"typecheck": "tsc --noEmit",
"ui:build": "vite build packages/ui",
"ui:dev": "vite packages/ui"
"ui:dev": "vite packages/ui",
"ui:test": "npm -C packages/ui run test:run"
},
"devDependencies": {
"@antfu/eslint-config": "^0.18.9",
Expand Down Expand Up @@ -56,7 +57,7 @@
"rollup-plugin-esbuild": "^4.8.2",
"rollup-plugin-license": "^2.6.1",
"typescript": "^4.6.2",
"vite": "^2.8.6",
"vite": "2.9.0-beta.3",
"vitepress": "^0.22.3",
"vitest": "workspace:*",
"vue": "^3.2.31"
Expand Down
30 changes: 30 additions & 0 deletions packages/ui/client/components/dashboard/DashboardEntry.cy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import faker from '@faker-js/faker'
import DashboardEntry from './DashboardEntry.vue'

const body = () => (<div data-testid="body-content">{ faker.lorem.words(2) }</div>)
const header = () => (<div data-testid="header-content">{ faker.hacker.phrase() }</div>)
const bodySelector = '[data-testid=body-content]'
const headerSelector = '[data-testid=header-content]'
const tailSelector = '[data-testid=tail]'

describe('DashboardEntry', () => {
it('tail is rendered by default', () => {
cy.mount(<DashboardEntry v-slots={{ body, header }}/>)
.get(tailSelector)
.should('exist')
})

it('tail is not shown when true', () => {
cy.mount(<DashboardEntry tail v-slots={{ body, header }}/>)
.get(tailSelector)
.should('not.exist')
})

it('renders the body and header slots', () => {
cy.mount(<DashboardEntry v-slots={{ body, header }}/>)
.get(bodySelector)
.should('be.visible')
.get(headerSelector)
.should('be.visible')
})
})
2 changes: 1 addition & 1 deletion packages/ui/client/components/dashboard/DashboardEntry.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ withDefaults(defineProps<{ tail?: boolean }>(), { tail: false })
<slot name="header" />
</div>
</div>
<div v-if="!tail" my-2 op50 w-1px bg-current origin-center rotate-15 translate-x-3 />
<div v-if="!tail" data-testid="tail" my-2 op50 w-1px bg-current origin-center rotate-15 translate-x-3 />
</div>
</template>
5 changes: 3 additions & 2 deletions packages/ui/client/components/dashboard/TestFilesEntry.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import { filesFailed, filesSnapshotFailed, filesSuccess, time } from '../../comp

<template>
<div
data-testid="test-files-entry"
grid="~ cols-[min-content_1fr_min-content]"
items-center gap="x-2 y-3" p="x4" relative font-light w-80
op80
>
<div i-carbon-document />
<div>Files</div>
<div class="number">
<div class="number" data-testid="num-files">
{{ files.length }}
</div>

Expand Down Expand Up @@ -45,7 +46,7 @@ import { filesFailed, filesSnapshotFailed, filesSuccess, time } from '../../comp

<div i-carbon-timer />
<div>Time</div>
<div class="number">
<div class="number" data-testid="run-time">
{{ time }}
</div>
</div>
Expand Down
10 changes: 5 additions & 5 deletions packages/ui/client/components/dashboard/TestsEntry.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,39 +14,39 @@ const pending = computed(() => {

<template>
<div flex="~ wrap" justify-evenly gap-2 p="x-4" relative>
<DashboardEntry text-green5>
<DashboardEntry text-green5 data-testid="pass-entry">
<template #header>
Pass
</template>
<template #body>
{{ pass }}
</template>
</DashboardEntry>
<DashboardEntry :class="{ 'text-red5': failed, 'op50': !failed }">
<DashboardEntry :class="{ 'text-red5': failed, 'op50': !failed }" data-testid="fail-entry">
<template #header>
Fail
</template>
<template #body>
{{ failed }}
</template>
</DashboardEntry>
<DashboardEntry v-if="skipped" op50>
<DashboardEntry v-if="skipped" op50 data-testid="skipped-entry">
<template #header>
Skip
</template>
<template #body>
{{ skipped }}
</template>
</DashboardEntry>
<DashboardEntry v-if="todo" op50>
<DashboardEntry v-if="todo" op50 data-testid="todo-entry">
<template #header>
Todo
</template>
<template #body>
{{ todo }}
</template>
</DashboardEntry>
<DashboardEntry :tail="true">
<DashboardEntry :tail="true" data-testid="total-entry">
<template #header>
Total
</template>
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/client/components/views/ViewConsoleOutput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ function getTaskName(id?: string) {
</script>

<template>
<div v-if="logs?.length" h-full class="scrolls" flex flex-col>
<div v-if="logs?.length" h-full class="scrolls" flex flex-col data-testid="logs">
<div v-for="log of logs" :key="log.taskId" font-mono>
<div border="b base" p-4>
<div
Expand Down
1 change: 1 addition & 0 deletions packages/ui/client/components/views/ViewEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ async function onSave(content: string) {
h-full
v-bind="{ lineNumbers: true }"
:mode="ext"
data-testid="code-mirror"
@save="onSave"
/>
</template>
27 changes: 27 additions & 0 deletions packages/ui/client/global-setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/// <reference types="vite-plugin-pages/client" />

import { createRouter as _createRouter, createWebHistory } from 'vue-router'
import FloatingVue, { VTooltip } from 'floating-vue'
import routes from 'virtual:generated-pages'
import 'd3-graph-controller/default.css'
import 'splitpanes/dist/splitpanes.css'
import '@unocss/reset/tailwind.css'
import 'codemirror/lib/codemirror.css'
import 'codemirror-theme-vars/base.css'
import './styles/main.css'
import 'floating-vue/dist/style.css'
import 'uno.css'

export const directives = {
tooltip: VTooltip,
}

FloatingVue.options.instantMove = true
FloatingVue.options.distance = 10

export const createRouter = () => _createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes,
})

export const plugins = [createRouter]
26 changes: 7 additions & 19 deletions packages/ui/client/main.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,15 @@
import { createApp } from 'vue'
import { createRouter, createWebHistory } from 'vue-router'
import routes from 'virtual:generated-pages'
import FloatingVue, { VTooltip } from 'floating-vue'
import { directives, plugins } from './global-setup'
import App from './App.vue'

import 'd3-graph-controller/default.css'
import 'splitpanes/dist/splitpanes.css'
import '@unocss/reset/tailwind.css'
import 'codemirror/lib/codemirror.css'
import 'codemirror-theme-vars/base.css'
import 'floating-vue/dist/style.css'
import './styles/main.css'
import 'uno.css'

const app = createApp(App)
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes,

plugins.forEach((plugin) => {
app.use(plugin)
})
app.use(router)

app.directive('tooltip', VTooltip)
FloatingVue.options.instantMove = true
FloatingVue.options.distance = 10
Object.entries(directives).forEach(([name, directive]) => {
app.directive(name, directive)
})

app.mount('#app')
7 changes: 7 additions & 0 deletions packages/ui/cypress.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"testFiles": "**/*.cy.{js,ts,jsx,tsx}",
"componentFolder": "client",
"supportFile": "cypress/support/index.ts",
"pluginsFile": "cypress/plugins/index.ts",
"fixturesFolder": false
}
15 changes: 15 additions & 0 deletions packages/ui/cypress/plugins/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import path from 'path'
import { startDevServer } from '@cypress/vite-dev-server'

const plugin: Cypress.PluginConfig = (on, config) => {
on('dev-server:start', options => startDevServer({
options,
viteConfig: {
configFile: path.resolve(__dirname, './vite.config.ts'),
},
}))

return config
}

export default plugin
7 changes: 7 additions & 0 deletions packages/ui/cypress/plugins/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { defineConfig } from 'vite'
import vueJsx from '@vitejs/plugin-vue-jsx'
import { config } from '../../vite.config'

config.plugins?.push(vueJsx())

export default defineConfig(config)
10 changes: 10 additions & 0 deletions packages/ui/cypress/support/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import faker from '@faker-js/faker'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haha, happy to see we use it! 🙌

import '../../client/global-setup'

import { registerMount } from './mount'

before(() => {
faker.seed(0)
})

registerMount()
31 changes: 31 additions & 0 deletions packages/ui/cypress/support/mount.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { mount } from '@cypress/vue'
import type { Component } from 'vue'
import { directives, plugins } from '../../client/global-setup'

export const registerMount = () => Cypress.Commands.add(
'mount',
// eslint-disable-next-line @typescript-eslint/no-unused-vars
<C extends Parameters<typeof mount>[0]>(comp: any, options: any = {}) => {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This C generic seems unused

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah thanks for talking about this. I really need help learning how to best type these wrapper functions. Typescript is not my first language... 😓

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should give a try of https://github.com/type-challenges/type-challenges!
In a stream, this could be fun to watch, especially with Anthony as mentor :P

options.global = options.global || {}
options.global.stubs = options.global.stubs || {}
options.global.stubs.transition = false
options.global.plugins = options.global.plugins || []
options.global.directives = directives
plugins?.forEach((pluginFn: () => any) => {
options?.global?.plugins?.push(pluginFn())
})

return mount(comp, options)
},
)

declare global {
namespace Cypress {
interface Chainable {
/**
* Install all vue plugins and globals then mount
*/
mount<Props = any>(comp: Component<Props>, options?: unknown): Cypress.Chainable<any>
}
}
}
39 changes: 35 additions & 4 deletions packages/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,32 +28,63 @@
"build:node": "rollup -c",
"dev:client": "vite",
"dev": "rollup -c --watch --watch.include=node/**",
"dev:ui": "run-p dev dev:client"
"dev:ui": "run-p dev dev:client",
"test:run": "cypress run-ct",
"test:open": "cypress open-ct"
},
"dependencies": {
"sirv": "^2.0.2"
},
"devDependencies": {
"@cypress/vite-dev-server": "^2.2.2",
"@cypress/vue": "^3.1.0",
"@faker-js/faker": "^6.0.0",
"@types/codemirror": "^5.60.5",
"@types/d3-force": "^3.0.3",
"@types/d3-selection": "^3.0.2",
"@types/ws": "^8.5.3",
"@unocss/reset": "^0.29.5",
"@vitejs/plugin-vue-jsx": "^1.3.3",
"@vitejs/plugin-vue": "^2.2.4",
"@vitest/ws-client": "workspace:*",
"@vueuse/core": "^8.1.2",
"codemirror": "^5.65.2",
"birpc": "^0.1.0",
"codemirror-theme-vars": "^0.1.1",
"codemirror": "^5.65.2",
"cypress": "^9.5.0",
"d3-graph-controller": "^2.2.18",
"flatted": "^3.2.4",
"floating-vue": "^2.0.0-y.0",
"picocolors": "^1.0.0",
"rollup": "^2.70.1",
"splitpanes": "^3.1.1",
"unocss": "^0.29.5",
"unplugin-auto-import": "^0.6.6",
"unplugin-vue-components": "^0.18.3",
"vite-plugin-optimize-persist": "^0.1.2",
"vite-plugin-package-config": "^0.1.1",
"vite-plugin-pages": "^0.22.0",
"vue": "^3.2.31",
"vue-router": "^4.0.14"
"vue-router": "^4.0.14",
"vue": "^3.2.31"
},
"vite": {
"optimizeDeps": {
"include": [
"@cypress/vue",
"@faker-js/faker",
"@vueuse/core",
"birpc",
"codemirror",
"codemirror/addon/display/placeholder",
"codemirror/mode/javascript/javascript",
"codemirror/mode/jsx/jsx",
"codemirror/mode/xml/xml",
"d3-graph-controller",
"flatted",
"floating-vue",
"splitpanes",
"vue-router"
]
}
}
}
3 changes: 3 additions & 0 deletions packages/ui/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{
"compilerOptions": {
"jsx": "preserve"
},
"extends": "../../tsconfig.json",
"exclude": ["dist", "node_modules"]
}