Power Your Software Testing with AI Agents and Cloud
The Native AI-Agentic Cloud Platform to Supercharge Quality Engineering. Test Intelligently and Ship Faster.
- TestMu AI (Formerly LambdaTest)
- /
- Blog
- /
- Vue Testing Guide: Vitest, Playwright, and AI Agents
Vue Testing Guide: Vitest, Playwright, and AI Agents
Test Vue 3 components and composables with Vitest, run Playwright E2E tests on real browsers, and use AI coding agents to write and verify your Vue test suite.
Last Updated on:
A Vue component can pass every unit test and still break for users, because specs that run in jsdom never compute your CSS or fire native browser events. The official Vue testing guide describes the trade-off directly: browser-based runners catch style issues, native DOM events, cookies, local storage, and network failures that Node-based runners such as Vitest cannot, but they are orders of magnitude slower.
That trade-off is why Vue testing happens in layers. This guide builds a unit and component layer and an end-to-end layer for a Vue 3 todo feature, runs the end-to-end layer on Chrome, Firefox, and WebKit on the TestMu AI cloud grid, and shows where AI coding agents fit into each layer. The specs and configs below are the exact files behind the test output shown, from runs on September 30, 2026.
Overview
Vue testing checks that the components, composables, and user flows of a Vue app behave correctly before release. The official Vue guide pairs fast Vitest specs for components and composables with a smaller set of end-to-end tests in real browsers, so most Vue suites run many quick specs and a few full-flow browser checks.
Which Tools Cover Each Layer of Vue Testing?
- Vitest: The test runner that create-vue adds for Vue unit and component tests. Vitest runs specs in Node against a simulated DOM such as jsdom and reuses the app's Vite configuration, so Vue tests need no separate build setup.
- Vue Test Utils: The official component mounting library. Its mount() function renders a component with all of its children, while shallowMount() swaps every child component for a stub such as todo-item-stub.
- Playwright: An end-to-end runner that drives Chromium, Firefox, and WebKit from one Vue test file. A cloud grid such as TestMu AI runs the same Playwright test on all three engines in parallel.
- Cypress: An end-to-end runner that the official Vue guide recommends alongside Playwright, known for its graphical interface and debugging. Cypress Component Testing also covers Vue components whose behavior depends on real styles or native DOM events.
- AI coding agents: Agents such as Claude Code can draft Vitest specs and Playwright tests from your components, and Playwright's planner, generator, and healer agents automate E2E authoring. A reviewer still checks every assertion before merge.
What Is Vue Testing?
Vue testing checks a Vue app at three levels: unit tests for logic such as composables, component tests that mount a component and assert on what it renders and emits, and end-to-end tests that drive the running app in a real browser.
According to W3Techs, Vue.js runs on 0.6% of all websites, which is 0.8% of the sites whose JavaScript library W3Techs can identify.
Each level has a tool the Vue guide recommends:
| Level | What it checks | Recommended tool | Runs in |
|---|---|---|---|
| Unit | Composables and plain functions | Vitest | Node |
| Component | Props, events, and rendered output of one component | Vitest with Vue Test Utils, or Cypress Component Testing | Node with jsdom or happy-dom, or a real browser with Cypress |
| End-to-end | Complete user flows in the built app | Playwright or Cypress | Real browsers |
At every level, the guide asks for assertions on what a component renders and emits rather than on its private state, because tests tied to implementation details break whenever the implementation changes.
How Do You Set Up Vitest for a Vue Project?
Scaffold the project with create-vue, the official Vue project generator, and select Vitest and Playwright. The Vue guide recommends Vitest because it reuses the same Vite configuration and transform pipeline as the app, and Vitest is created and maintained by Vue and Vite team members.
npm create vue@latest vue-testing-demo -- --vitest --playwright --bare
cd vue-testing-demo
npm installThe --vitest and --playwright flags add both runners without the interactive prompts, and --bare leaves out the example components. On September 30, 2026, create-vue 3.24.0 pinned Vitest ^4.1.11, @vue/test-utils ^2.5.0, jsdom ^30.0.1, and @playwright/test ^1.63.0, and generated this vitest.config.js:
import { fileURLToPath } from 'node:url'
import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
import viteConfig from './vite.config.js'
export default mergeConfig(
viteConfig,
defineConfig({
test: {
environment: 'jsdom',
exclude: [...configDefaults.exclude, 'e2e/**'],
root: fileURLToPath(new URL('./', import.meta.url)),
},
}),
)environment: 'jsdom' gives each spec a simulated DOM to mount components into, and the exclude entry keeps Vitest away from the Playwright specs in e2e/. The scaffold also adds two scripts: npm run test:unit for Vitest and npm run test:e2e for Playwright.
For an existing Vite project, install the same packages and copy the config above:
npm install -D vitest @vue/test-utils jsdomA fresh install pulls Vitest 5.0.2, the latest release at the time of writing, and the suite in this guide passes on both versions. Teams moving from Jest can weigh the switch in Vitest vs Jest, and Nuxt projects follow the setup in the Nuxt testing guide.
How Do You Test a Vue Component With Vue Test Utils?
Vue Test Utils mounts a component into the simulated DOM and returns a wrapper you can query and interact with. The examples use two single-file components: TodoItem renders one todo and emits toggle, and TodoList adds todos through a form.
<script setup>
defineProps({
todo: { type: Object, required: true },
})
const emit = defineEmits(['toggle'])
</script>
<template>
<li data-test="todo" :class="{ completed: todo.done }">
<input type="checkbox" :checked="todo.done" @change="emit('toggle', todo.id)" />
<span>{{ todo.text }}</span>
</li>
</template><script setup>
import { ref } from 'vue'
import TodoItem from './TodoItem.vue'
import { useTodos } from '../composables/useTodos'
const { todos, remaining, add, toggle } = useTodos()
const draft = ref('')
function submit() {
add(draft.value)
draft.value = ''
}
</script>
<template>
<form @submit.prevent="submit">
<input v-model="draft" data-test="new-todo" placeholder="What needs to be done?" />
</form>
<ul>
<TodoItem v-for="todo in todos" :key="todo.id" :todo="todo" @toggle="toggle" />
</ul>
<p data-test="remaining">{{ remaining }} left</p>
</template>TodoList keeps its state in a useTodos composable, which gets its own spec in the composables section:
import { ref, computed } from 'vue'
export function useTodos() {
const todos = ref([])
let nextId = 1
const remaining = computed(() => todos.value.filter((todo) => !todo.done).length)
function add(text) {
const trimmed = text.trim()
if (!trimmed) return
todos.value.push({ id: nextId++, text: trimmed, done: false })
}
function toggle(id) {
const todo = todos.value.find((item) => item.id === id)
if (todo) todo.done = !todo.done
}
return { todos, remaining, add, toggle }
}A component spec checks the public contract: props in, rendered output and emitted events out. This one covers TodoItem:
import { describe, it, expect } from 'vitest'
import { mount } from '@vue/test-utils'
import TodoItem from '../components/TodoItem.vue'
describe('TodoItem', () => {
it('renders the todo text from props', () => {
const wrapper = mount(TodoItem, {
props: { todo: { id: 7, text: 'Check the emitted event', done: false } },
})
expect(wrapper.text()).toContain('Check the emitted event')
})
it('emits toggle with the todo id when the checkbox changes', async () => {
const wrapper = mount(TodoItem, {
props: { todo: { id: 7, text: 'Check the emitted event', done: false } },
})
await wrapper.get('input[type="checkbox"]').trigger('change')
expect(wrapper.emitted('toggle')).toEqual([[7]])
})
})wrapper.emitted('toggle') returns every payload the component emitted, so the spec verifies the event a parent listens for without touching the component instance. The TodoList spec drives the form the way a user would:
import { describe, it, expect } from 'vitest'
import { mount, shallowMount } from '@vue/test-utils'
import TodoList from '../components/TodoList.vue'
import TodoItem from '../components/TodoItem.vue'
async function addTodo(wrapper, text) {
await wrapper.get('[data-test="new-todo"]').setValue(text)
await wrapper.get('form').trigger('submit')
}
describe('TodoList', () => {
it('adds a todo and updates the remaining count', async () => {
const wrapper = mount(TodoList)
await addTodo(wrapper, 'Write component tests')
expect(wrapper.findAll('[data-test="todo"]')).toHaveLength(1)
expect(wrapper.get('[data-test="remaining"]').text()).toBe('1 left')
})
it('marks a todo as done when its checkbox is checked', async () => {
const wrapper = mount(TodoList)
await addTodo(wrapper, 'Review agent-written tests')
await wrapper.get('input[type="checkbox"]').setValue(true)
expect(wrapper.get('[data-test="todo"]').classes()).toContain('completed')
expect(wrapper.get('[data-test="remaining"]').text()).toBe('0 left')
})
it('stubs TodoItem when shallow mounted', async () => {
const wrapper = shallowMount(TodoList)
await addTodo(wrapper, 'Stubbed child')
expect(wrapper.findAllComponents(TodoItem)).toHaveLength(1)
expect(wrapper.find('[data-test="todo"]').exists()).toBe(false)
console.log(wrapper.html())
})
})Keep these Vue Test Utils behaviors in mind when you extend the specs:
- Await DOM updates -
setValue()andtrigger()return Vue'snextTickpromise, so awaiting them lets Vue re-render before the next assertion runs. - get() vs find() -
get()throws when nothing matches, which fails the spec with a clear message, whilefind()returns a wrapper you check withexists()when asserting that an element is absent. - data-test selectors - selecting by
data-testattributes keeps specs independent of CSS classes and markup refactors.
Austin Siewert
Co-Founder, Steadfast Systems
Discovered @TestMu AI yesterday. Best browser testing tool I've found for my use case. Great pricing model for the limited testing I do 👏
2M+ Devs and QAs rely on TestMu AI
Deliver immersive digital experiences with Next-Generation Mobile Apps and Cross Browser Testing Cloud
What Is the Difference Between mount() and shallowMount()?
mount() renders a component together with its full tree of child components, while shallowMount() renders only the component and replaces each child component with a stub. The third TodoList spec above shallow-mounts the list and prints its HTML:
<form><input data-test="new-todo" placeholder="What needs to be done?"></form>
<ul>
<todo-item-stub todo="[object Object]"></todo-item-stub>
</ul>
<p data-test="remaining">1 left</p>TodoItem became <todo-item-stub>, so the spec can still count TodoItem instances with findAllComponents(), but the checkbox and text that the real child renders are gone. That isolation helps when a child is expensive to render or has side effects such as fetching data on mount.
For everyday specs, the Vue Test Utils guide to stubs leans toward mount(): the more you stub, the less production-like the test becomes, and for one or two irrelevant children it suggests mount() with the stubs option instead.
| Aspect | mount() | shallowMount() |
|---|---|---|
| Child components | Rendered for real | Replaced with stubs such as todo-item-stub |
| Parent-child bugs | Caught, because both components run | Missed, because the child never runs |
| Best fit | Default for component specs | Children that are slow or have side effects you cannot mock |
How Do You Test Vue Composables?
A composable is a function that packages stateful logic with Vue's Composition API. The Vue guide splits testing into two cases: a composable that only uses reactivity APIs can be called directly, while one that uses lifecycle hooks or provide/inject needs a host component instance.
useTodos only uses ref() and computed(), so its spec calls it like any function:
import { describe, it, expect } from 'vitest'
import { useTodos } from '../composables/useTodos'
describe('useTodos', () => {
it('ignores blank input and counts remaining todos', () => {
const { todos, remaining, add, toggle } = useTodos()
add(' ')
add('Test the composable directly')
add('Skip the host component')
toggle(1)
expect(todos.value).toHaveLength(2)
expect(remaining.value).toBe(1)
})
})usePersistedTodos loads saved todos in onMounted() and writes changes back with watch(). Called outside a component, its onMounted() hook never fires:
import { ref, watch, onMounted } from 'vue'
export function usePersistedTodos(key = 'todos') {
const todos = ref([])
onMounted(() => {
todos.value = JSON.parse(localStorage.getItem(key) ?? '[]')
})
watch(todos, (value) => localStorage.setItem(key, JSON.stringify(value)), { deep: true })
return { todos }
}The Vue guide's withSetup() helper mounts a throwaway app whose setup() runs the composable, and returns the app so a spec can call app.provide() or app.unmount():
import { createApp } from 'vue'
export function withSetup(composable) {
let result
const app = createApp({
setup() {
result = composable()
// suppress missing template warning
return () => {}
},
})
app.mount(document.createElement('div'))
// return the result and the app instance
// for testing provide/unmount
return [result, app]
}import { describe, it, expect, beforeEach } from 'vitest'
import { nextTick } from 'vue'
import { withSetup } from '../test-utils/withSetup'
import { usePersistedTodos } from '../composables/usePersistedTodos'
describe('usePersistedTodos', () => {
beforeEach(() => localStorage.clear())
it('loads saved todos when its host component mounts', () => {
localStorage.setItem('todos', JSON.stringify([{ id: 1, text: 'Saved earlier', done: false }]))
const [result, app] = withSetup(() => usePersistedTodos())
expect(result.todos.value[0].text).toBe('Saved earlier')
app.unmount()
})
it('writes changes back to localStorage', async () => {
const [result, app] = withSetup(() => usePersistedTodos())
result.todos.value.push({ id: 2, text: 'Persist me', done: false })
await nextTick()
expect(JSON.parse(localStorage.getItem('todos'))).toHaveLength(1)
app.unmount()
})
})The await nextTick() line matters. With it removed, the watcher has not flushed yet, localStorage.getItem('todos') still returns null, and the spec fails with "Target cannot be null or undefined."
Run the whole suite with the verbose reporter to see each spec:
npx vitest run --reporter=verbose ✓ src/__tests__/useTodos.spec.js > useTodos > ignores blank input and counts remaining todos 4ms
✓ src/__tests__/usePersistedTodos.spec.js > usePersistedTodos > loads saved todos when its host component mounts 13ms
✓ src/__tests__/usePersistedTodos.spec.js > usePersistedTodos > writes changes back to localStorage 3ms
✓ src/__tests__/TodoItem.spec.js > TodoItem > renders the todo text from props 18ms
✓ src/__tests__/TodoItem.spec.js > TodoItem > emits toggle with the todo id when the checkbox changes 15ms
stdout | src/__tests__/TodoList.spec.js > TodoList > stubs TodoItem when shallow mounted
<form><input data-test="new-todo" placeholder="What needs to be done?"></form>
<ul>
<todo-item-stub todo="[object Object]"></todo-item-stub>
</ul>
<p data-test="remaining">1 left</p>
✓ src/__tests__/TodoList.spec.js > TodoList > adds a todo and updates the remaining count 42ms
✓ src/__tests__/TodoList.spec.js > TodoList > marks a todo as done when its checkbox is checked 8ms
✓ src/__tests__/TodoList.spec.js > TodoList > stubs TodoItem when shallow mounted 12ms
Test Files 4 passed (4)
Tests 8 passed (8)
Start at 16:35:38
Duration 1.58s (transform 199ms, setup 0ms, import 698ms, tests 123ms, environment 4.21s)All eight specs passed in 1.58 seconds on Vitest 4.1.11, including the shallow-mount spec whose stub HTML appears in the output.
How Do You Run Vue E2E Tests on Real Browsers?
jsdom approximates a browser, so it cannot show whether a flow works in WebKit, the engine behind Safari, or in Firefox. An end-to-end test drives the built app in real browsers instead. For this layer the Vue guide recommends Playwright, which supports Chromium, WebKit, and Firefox, or Cypress.
The test below targets the TodoMVC Vue example, a public Vue 3 build, so it runs without exposing a local server:
import { test, expect } from './lambdatest-setup.js'
test('adds, completes, and filters todos in the Vue TodoMVC app', async ({ page }) => {
await page.goto('https://todomvc.com/examples/vue/dist/')
const newTodo = page.getByPlaceholder('What needs to be done?')
await newTodo.fill('Write Vitest specs')
await newTodo.press('Enter')
await newTodo.fill('Run E2E tests on real browsers')
await newTodo.press('Enter')
const todos = page.locator('.todo-list li')
await expect(todos).toHaveCount(2)
await todos.first().getByRole('checkbox').check()
await expect(todos.first()).toHaveClass(/completed/)
await expect(page.locator('.todo-count')).toHaveText('1 item left')
await page.getByRole('link', { name: 'Active' }).click()
await expect(todos).toHaveCount(1)
await expect(todos.first()).toHaveText('Run E2E tests on real browsers')
})The ./lambdatest-setup.js fixture is a JavaScript port of the cloud fixture in TestMu AI's Playwright skill. Projects whose name ends in @lambdatest connect to a remote browser at wss://cdp.lambdatest.com/playwright, other projects launch a local browser, and each cloud session reports its pass or fail status back to the dashboard:
import { test as base, chromium } from '@playwright/test'
import { execSync } from 'node:child_process'
const pwVersion = execSync('npx playwright --version').toString().trim().split(' ')[1]
export const test = base.extend({
page: async ({}, use, testInfo) => {
const projectName = testInfo.project.name
if (projectName.includes('@lambdatest')) {
const [browserName, browserVersion, platform] = projectName.split('@lambdatest')[0].split(':')
const capabilities = {
browserName,
browserVersion,
'LT:Options': {
platform,
build: 'Vue TodoMVC E2E',
name: testInfo.title,
user: process.env.LT_USERNAME,
accessKey: process.env.LT_ACCESS_KEY,
network: true,
video: true,
console: true,
playwrightClientVersion: pwVersion,
},
}
const browser = await chromium.connect({
wsEndpoint: `wss://cdp.lambdatest.com/playwright?capabilities=${encodeURIComponent(JSON.stringify(capabilities))}`,
})
const context = await browser.newContext(testInfo.project.use)
const ltPage = await context.newPage()
await use(ltPage)
const status = testInfo.status === 'passed' ? 'passed' : 'failed'
const remark = testInfo.error?.message || 'OK'
await ltPage.evaluate(
() => {},
`lambdatest_action: ${JSON.stringify({ action: 'setTestStatus', arguments: { status, remark } })}`,
)
await ltPage.close()
await context.close()
await browser.close()
} else {
const browser = await chromium.launch()
const context = await browser.newContext()
const page = await context.newPage()
await use(page)
await context.close()
await browser.close()
}
},
})
export { expect } from '@playwright/test'Each project name encodes the browser, version, and platform that the fixture parses:
import { defineConfig } from '@playwright/test'
export default defineConfig({
testDir: './e2e',
testMatch: 'todomvc.spec.js',
timeout: 90 * 1000,
reporter: 'list',
projects: [
{ name: 'chrome:latest:Windows 11@lambdatest' },
{ name: 'pw-firefox:latest:Windows 11@lambdatest' },
{ name: 'pw-webkit:latest:macOS Sequoia@lambdatest' },
],
})Export your credentials and run the suite:
export LT_USERNAME=<your-username>
export LT_ACCESS_KEY=<your-access-key>
npx playwright test --config=playwright.lambdatest.config.js
Running 3 tests using 3 workers
ok 3 [chrome:latest:Windows 11@lambdatest] › e2e\todomvc.spec.js:3:1 › adds, completes, and filters todos in the Vue TodoMVC app (16.9s)
ok 2 [pw-webkit:latest:macOS Sequoia@lambdatest] › e2e\todomvc.spec.js:3:1 › adds, completes, and filters todos in the Vue TodoMVC app (33.9s)
ok 1 [pw-firefox:latest:Windows 11@lambdatest] › e2e\todomvc.spec.js:3:1 › adds, completes, and filters todos in the Vue TodoMVC app (46.5s)
3 passed (50.5s)The same Vue flow passed in Chrome, Firefox, and WebKit in one 50.5-second parallel run, with chrome:latest resolving to Chrome 154 on the grid. The first attempt requested WebKit on macOS Ventura, and the grid rejected it: WebKit on Playwright 1.58 or later needs macOS Sonoma or newer, so the final config uses macOS Sequoia.
The fixture's network, video, and console options capture network logs, a session recording, and console logs for every run on the TestMu AI Automation Cloud, which runs existing Playwright, Cypress, and Selenium suites across 3,000+ browser and OS combinations. When a Vue flow fails in one engine only, those artifacts show what that browser rendered and requested.
To test a Vue app on localhost instead of a public URL, run the TestMu AI Tunnel so the cloud browsers can reach your machine.
Note: Run your Vue Playwright suite on Chrome, Firefox, and WebKit without maintaining a browser grid. Try TestMu AI free
How Do AI Agents Change Vue Testing?
An AI coding agent can draft every spec in this guide from the components alone. The risk is that a spec can pass while encoding the agent's own wrong assumption, so the tools below give the agent tested patterns, a real browser to verify against, and a human reviewer.
Install the Vitest and Playwright Agent Skills
TestMu AI publishes open-source agent skills that teach coding agents framework-specific patterns. Install the Vitest and Playwright skills in the Vue project:
npx agentskillsforall add https://github.com/LambdaTest/agent-skills.git --skill vitest-skill
npx agentskillsforall add https://github.com/LambdaTest/agent-skills.git --skill playwright-skillThe installer asks which agents to install into, including Claude Code, Cursor, GitHub Copilot, and Gemini CLI. The Vitest skill steers agents toward vi.fn() and vi.mock() instead of Jest's jest.fn(), and the Playwright skill ships the cloud fixture used in the E2E section above.
Generate E2E Tests With Playwright Test Agents
Playwright ships three test agents: the planner explores the app and writes a Markdown test plan, the generator turns the plan into Playwright test files, and the healer runs the suite and repairs failing tests. Initializing them in this guide's Vue project for Claude Code printed:
npx playwright init-agents --loop=claude 🎭 Using project "chromium" as a primary project
📝 specs\README.md - directory for test plans
🌱 e2e\seed.spec.ts - default environment seed file
🤖 .claude\agents\playwright-test-generator.md - agent definition
🤖 .claude\agents\playwright-test-healer.md - agent definition
🤖 .claude\agents\playwright-test-planner.md - agent definition
🔧 .mcp.json - mcp configuration
✅ Done.The three files in .claude/agents are Claude Code subagent definitions that call the playwright-test MCP server registered in .mcp.json. seed.spec.ts holds the setup the planner needs before it explores, such as signing in, and --loop also accepts vscode, codex, and opencode.
Review the healer's changes closely. Its definition grants edit and write access to your test files, so a "fix" can loosen an assertion instead of fixing the app.
Verify the Rendered UI With Kane CLI
Vitest and Playwright specs prove only what their author thought to assert. Kane CLI gives a coding agent a real Chrome browser and a natural-language objective: the agent states the outcome, Kane CLI drives the browser, and agent mode streams NDJSON events that end in a run_end result the agent can parse.
Kane CLI decides when to act by watching the rendered screen instead of DOM or network signals, which suits Vue components that lazy-render or suspend, such as those wrapped in Suspense. An objective for the TodoMVC flow looks like this:
npm install -g @testmuai/kane-cli
kane-cli run "Add the todos 'Write Vitest specs' and 'Run E2E tests on real browsers', check the first todo, and assert the footer shows '1 item left'" \
--url https://todomvc.com/examples/vue/dist/ \
--agent --headless \
--username "$LT_USERNAME" --access-key "$LT_ACCESS_KEY"The exit code carries the verdict: 0 when the objective passes, 1 when an assertion fails, 2 on an environment error, and 3 on a timeout. Pass --ws-endpoint with a TestMu AI wss:// URL to run the same objective on a cloud browser instead of local Chrome.
QA engineers who prefer not to write code can author the same flows in plain English with KaneAI; the guide on how to test Vue apps without code covers reactive forms, route guards, and async states.
In the workshop below, Siddhant Sinha of TestMu AI runs the full agentic QA loop with Kane CLI, turning plain-language requirements into tests and capturing every run as a portable evidence pack:
Review Agent-Written Vue Tests
Check agent-written specs for these patterns before merging:
- Private state assertions - specs that read
wrapper.vminternals break on refactors, and the Vue guide asks for assertions on rendered output and emitted events instead. - Missing awaits - an assertion placed after
setValue()ortrigger()withoutawaitreads the DOM before Vue re-renders. - Stubs that hide bugs - a parent tested only with
shallowMount()passes even when the real child breaks, so keep at least onemount()spec per parent-child pair. - Mocked subject - a
vi.mock()that replaces the module under test turns the spec into a test of the mock. - Loosened assertions - when an agent or the healer "fixes" a failing test, compare the old and new assertion before trusting the green result.
Let Claude Code write Playwright E2E tests for your Vue app that actually pass.
Conclusion
Start your Vue testing setup with npm create vue@latest, adapt the specs above to your own components, and move the Playwright suite onto real browsers by following the guide to run Playwright tests on TestMu AI. Once both layers run in CI, install the Vitest and Playwright skills so your coding agent writes new specs in the same style.
Author
Harish Rajora is a software developer at TestMu AI with over 6 years of hands-on experience in Python and cross-platform application development across Windows, macOS, and Linux. He has authored 800+ technical articles and worked on large-scale projects, including GenAI applications and core engineering features used by millions. Harish has led DevOps initiatives building CI/CD pipelines with Jenkins, AWS, GitLab, and GitHub, and holds an M.Tech in Software Engineering from IIIT Allahabad.
Reviewer
Rahul Mishra is a Lead Member of Technical Staff at TestMu AI (formerly LambdaTest), leading frontend engineering and accessibility testing across the quality engineering platform. He mentors frontend engineers, runs code reviews and sprint planning, optimizes React.js rendering performance, and makes product features accessible to users with disabilities through WCAG and ADA-compliant accessibility audits. He brings 10+ years of experience across React.js, VueJS, TypeScript, Swift, Objective-C, and AWS, with earlier work as a Technical Lead at VectoScalar Technologies. Rahul holds a B.E. in Information Technology.
Vue Testing FAQs
Did you find this page helpful?
More Related Blogs
TestMu AI forEnterprise
Get access to solutions built on Enterprise
grade security, privacy, & compliance
- Advanced access controls
- Advanced data retention rules
- Advanced Local Testing
- Premium Support options
- Early access to beta features
- Private Slack Channel
- Unlimited Manual Accessibility DevTools Tests





