-
-
Notifications
You must be signed in to change notification settings - Fork 1k
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
antfu
merged 28 commits into
vitest-dev:main
from
JessicaSachs:jess/adding-cy-component-tests
Mar 21, 2022
Merged
Changes from 16 commits
Commits
Show all changes
28 commits
Select commit
Hold shift + click to select a range
860f8de
docs: additional cypress + vitest comparison content
JessicaSachs d9d4754
feat: ui testing
edimitchel 4150f74
fix: seperate cypress tests
edimitchel 7a60412
Merge branch 'vitest-dev:main' into main
JessicaSachs 6c8ec2a
feat: adding cypress component testing for ui
JessicaSachs 205e987
chore: share the common deps for global app setup
JessicaSachs b78b171
Merge remote-tracking branch 'origin/main' into jess/adding-cy-compon…
JessicaSachs d042221
spacing
JessicaSachs bd26fe8
Merge remote-tracking branch 'origin/main' into jess/adding-cy-compon…
JessicaSachs 0f0cf9f
Update package.json
JessicaSachs ea4c8a5
chore: adding OptimizationPersist + PkgConfig to reduce flake
JessicaSachs 9e0ab89
Merge branch 'jess/adding-cy-component-tests' of https://github.com/J…
JessicaSachs 343ca1f
chore: workaround for unocss hmr
JessicaSachs c5317d8
chore: adding ts-ignore comments
JessicaSachs 8fb64c2
chore: reordering data-testid
JessicaSachs c16d457
chore: ts-expect-error
JessicaSachs 09bdb65
--allow-empty
JessicaSachs 8c1269f
bug: reproduction of failing vite + cypress setup
JessicaSachs bc8514f
chore: adding Vite 2.9.0-beta.3 to cold-start stability issues for UI…
JessicaSachs c378713
Merge remote-tracking branch 'origin/main' into jess/adding-cy-compon…
JessicaSachs 9a9c9df
chore: fixing types
JessicaSachs 70b3359
chore: fixing types
JessicaSachs 91fa5da
reenabling tests
JessicaSachs 09cf89e
adding faker seed back in
JessicaSachs 939ebdb
bumping faker version
JessicaSachs 60b136b
Merge branch 'main' into jess/adding-cy-component-tests
antfu c8e8d61
Merge branch 'main' into jess/adding-cy-component-tests
antfu 170f15a
Merge branch 'main' into jess/adding-cy-component-tests
antfu File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,3 +12,6 @@ dist | |
.idea | ||
.DS_Store | ||
bench/test/*/*/ | ||
cypress/videos | ||
cypress/downloads | ||
cypress/screenshots |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import IconButton from './IconButton.vue' | ||
|
||
const title = 'A star' | ||
const icon = 'i-carbon-star-filled' | ||
|
||
describe('IconButton', () => { | ||
it('should render the title', () => { | ||
cy.mount(<IconButton m="2" title={title} icon={icon}/>) | ||
.get(`[aria-label="${title}"][role=button]`) | ||
.should('be.visible') | ||
}) | ||
|
||
it('can be overridden with a slot', () => { | ||
cy.mount(<IconButton m="2" icon={icon}> | ||
<span text="32px">⭐️</span> | ||
</IconButton>) | ||
.get(`.${icon}`) | ||
.should('not.exist') | ||
.get('button') | ||
.contains('⭐️') | ||
.should('be.visible') | ||
}) | ||
}) |
35 changes: 35 additions & 0 deletions
35
packages/ui/client/components/dashboard/DashboardEntry.cy.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
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]' | ||
|
||
// Used as a workaround until unocss HMR is compatible w Cy. | ||
it('initial', () => { | ||
cy.mount(<DashboardEntry v-slots={{ body, header }}/>) | ||
}) | ||
|
||
describe('DashboardEntry', () => { | ||
it('tail is rendered by default 2', () => { | ||
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') | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 20 additions & 0 deletions
20
packages/ui/client/components/dashboard/TestFilesEntry.cy.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import TestFilesEntry from './TestFilesEntry.vue' | ||
|
||
const entrySelector = '[data-testid=test-files-entry]' | ||
const numFilesSelector = '[data-testid=num-files]' | ||
const timingSelector = '[data-testid=run-time]' | ||
|
||
describe('TestFilesEntry', () => { | ||
it('renders the headers', () => { | ||
cy.mount(<TestFilesEntry/>) | ||
.get(entrySelector) | ||
.should('contain.text', 'Files') | ||
.and('contain.text', 'Time') | ||
|
||
// Empty state | ||
.get(timingSelector) | ||
.should('have.text', '0ms') | ||
.get(numFilesSelector) | ||
.should('have.text', '0') | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import TestsEntry from './TestsEntry.vue' | ||
|
||
const passEntrySelector = '[data-testid=pass-entry]' | ||
const failEntrySelector = '[data-testid=fail-entry]' | ||
const totalEntrySelector = '[data-testid=total-entry]' | ||
const todoEntrySelector = '[data-testid=todo-entry]' | ||
const skippedEntrySelector = '[data-testid=skipped-entry]' | ||
|
||
describe('TestsEntry', () => { | ||
it('renders the headers for pass, fail, and total', () => { | ||
cy.mount(<TestsEntry/>) | ||
.get(passEntrySelector) | ||
.should('contain.text', 'Pass') | ||
.and('contain.text', '0') | ||
.get(failEntrySelector) | ||
.and('contain.text', 'Fail') | ||
.and('contain.text', '0') | ||
.get(totalEntrySelector) | ||
.and('contain.text', 'Total') | ||
.and('contain.text', '0') | ||
}) | ||
|
||
it('does not render skipped and todo unless there are tests matched', () => { | ||
cy.mount(<TestsEntry/>) | ||
.get(skippedEntrySelector) | ||
.should('not.exist') | ||
.get(todoEntrySelector) | ||
.should('not.exist') | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
packages/ui/client/components/dashboard/TestsFilesContainer.cy.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import TestsFilesContainer from './TestsFilesContainer.vue' | ||
|
||
const entrySelector = '[data-testid=test-files-entry]' | ||
|
||
describe('TestsFilesContainer', () => { | ||
it('renders the TestEntry', () => { | ||
cy.mount(<TestsFilesContainer/>) | ||
.get(entrySelector) | ||
.should('be.visible') | ||
}) | ||
}) |
13 changes: 13 additions & 0 deletions
13
packages/ui/client/components/views/ViewConsoleOutput.spec.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import ViewConsoleOutput from './ViewConsoleOutput.vue' | ||
|
||
const entrySelector = '[data-testid=logs]' | ||
|
||
describe('ViewConsoleOutput', () => { | ||
it('renders', () => { | ||
cy.mount(<ViewConsoleOutput/>) | ||
.get(entrySelector) | ||
// TODO: stub the websocket connection | ||
// so that we can add logs and other data | ||
.should('not.exist') | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import faker from '@faker-js/faker' | ||
import ViewEditor from './ViewEditor.vue' | ||
|
||
const viewEditorSelector = '[data-testid=code-mirror]' | ||
|
||
// TODO: stub out the rpc call in order to fully test this component | ||
describe('ViewEditor', () => { | ||
it('renders codemirror with line numbers', () => { | ||
const file = { | ||
filepath: faker.system.filePath(), | ||
collectDuration: faker.time.recent(), | ||
tasks: [], | ||
} | ||
cy.mount(<ViewEditor h="200px" file={file}/>) | ||
.get(viewEditorSelector) | ||
.type(`// ${faker.git.commitSha()}{enter}`, { delay: 0 }) | ||
.get(viewEditorSelector) | ||
.should('contain.text', '1') | ||
.and('contain.text', '2') | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
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] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import App from './index.vue' | ||
|
||
// When mocking WebSockets, we'll want to follow the guide here | ||
// https://glebbahmutov.com/blog/test-socketio-chat-using-cypress/#use-socketio-from-cypress | ||
describe('App', () => { | ||
it('should render', () => { | ||
cy.mount(<App />) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import faker from '@faker-js/faker' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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() |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we share and export that testids from components?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've never seen a pattern like that in a codebase, nor have I implemented it before because:
Instead of one step: Cmd+F
data-testid="pass-entry-selector"
You'd need to do two: Cmd+F
pass-entry-selector
and then Cmd+FpassEntrySelector
to find its usage within the template.[role="button"]
and other selector strategies are also valid, and you'd create an inconsistencyFor the implementation, I guess you would do:
I would never recommend doing this. I hope this helps answer your question.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... A bit of an off-topic aside, since you seem to be into the theory behind testing...
One of the patterns that isn't as common nowadays than it was for QA Engineers is the Page Object Model (POM) pattern. This pattern essentially has you build a Class representation of the "Pages" in your application. It was very common pre-2015 when writing Selenium tests.
and a test...
Cypress doesn't really have good patterns for PageObjectModel (We actually discourage users from doing it, though I've never really agreed with why.) I've considered exploring this pattern again from the perspective of developers instead of QA Engineers, but haven't done so.
The downsides are a superset of the downsides that come with OOP. The upsides are the same. It promises to offer composition through actions and data. For example a
CheckoutPage
may have aCheckoutForm
and you can compose with classes.Anyway, this is just an exercise in thought-leadership -- it's an uncommon and antiquated pattern at the moment and I wouldn't recommend it for production usage.
😅