Skip to content

test(vapor): use browser mode instead of pupeteer to run tests - #13934

Merged
edison1105 merged 16 commits into
vuejs:minorfrom
sheremet-va:test/rewrite-e2e-vapor-to-use-browser-mode
Mar 23, 2026
Merged

test(vapor): use browser mode instead of pupeteer to run tests#13934
edison1105 merged 16 commits into
vuejs:minorfrom
sheremet-va:test/rewrite-e2e-vapor-to-use-browser-mode

Conversation

@sheremet-va

@sheremet-va sheremet-va commented Sep 26, 2025

Copy link
Copy Markdown

This PR rewrites the tests for Vue Vapor mode to use Vitest Browser Mode. The logic of the test stayed the same, although it maybe also good to rewrite some of it or split it into separate tests. There are no big noticeable changes in speed.

Happy to get any feedback.

If there is desire, I can also update older e2e tests.

Running tests with --browser.headless=false also shows Vitest UI:

Screenshot 2025-09-26 at 17 29 01

@coderabbitai

coderabbitai Bot commented Sep 26, 2025

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 75a323d7-76a3-4e3f-ac90-5c1c008f0875

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

test('vapor', { timeout: E2E_TIMEOUT }, async () => {
createVaporApp(App).mount('#app')

expect(css('.main')).not.toBeVisible()

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Technically it's always better to use expect.element(locator).not.toBeVisible(), but prettier changes this 1 line into 3, so I kept more error prone version for esthetic reasons. I wonder if we can improve this on Vitest side.

.use(sirv(path.resolve(import.meta.dirname, '../dist')))
.listen(port)
process.on('SIGTERM', () => server && server.close())
test('vapor', { timeout: E2E_TIMEOUT }, async () => {

@sheremet-va sheremet-va Sep 26, 2025

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Putting timeout here makes prettier format the test body with indentation of 2 instead of 4, although maybe it's even better to move the timeout to the config.

Comment thread vitest.config.ts Outdated
},
{
extends: true,
extends: './packages-private/vapor-e2e-test/vite.config.ts',

@sheremet-va sheremet-va Sep 26, 2025

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

The test config reuses the Vite config from a private repo instead of the main one (so, aliases and defines are not actually inherited, but tests seem to run ok...)

@github-actions

github-actions Bot commented Sep 28, 2025

Copy link
Copy Markdown

Size Report

Bundles

File Size Gzip Brotli
compiler-dom.global.prod.js 86.4 kB 30.2 kB 26.6 kB
runtime-dom.global.prod.js 111 kB 41.9 kB 37.5 kB
vue.global.prod.js 170 kB 61.7 kB 55 kB

Usages

Name Size Gzip Brotli
createApp (CAPI only) 50.6 kB 19.8 kB 18 kB
createApp 59.6 kB 23.1 kB 21 kB
createApp + vaporInteropPlugin 85.9 kB 31.8 kB 28.7 kB
createVaporApp 28.8 kB (+113 B) 11.2 kB (+46 B) 10.2 kB (+45 B)
createSSRApp 63.9 kB 24.8 kB 22.5 kB
createVaporSSRApp 32.1 kB (+113 B) 12.4 kB (+46 B) 11.4 kB (+36 B)
defineCustomElement 66.2 kB 25.1 kB 22.8 kB
defineVaporCustomElement 39.5 kB (+113 B) 14.6 kB (+47 B) 13.4 kB (+50 B)
overall 74.5 kB 28.4 kB 25.8 kB

@pkg-pr-new

pkg-pr-new Bot commented Sep 28, 2025

Copy link
Copy Markdown

Open in StackBlitz

@vue/compiler-core

pnpm add https://pkg.pr.new/@vue/compiler-core@13934
npm i https://pkg.pr.new/@vue/compiler-core@13934
yarn add https://pkg.pr.new/@vue/compiler-core@13934.tgz

@vue/compiler-dom

pnpm add https://pkg.pr.new/@vue/compiler-dom@13934
npm i https://pkg.pr.new/@vue/compiler-dom@13934
yarn add https://pkg.pr.new/@vue/compiler-dom@13934.tgz

@vue/compiler-sfc

pnpm add https://pkg.pr.new/@vue/compiler-sfc@13934
npm i https://pkg.pr.new/@vue/compiler-sfc@13934
yarn add https://pkg.pr.new/@vue/compiler-sfc@13934.tgz

@vue/compiler-ssr

pnpm add https://pkg.pr.new/@vue/compiler-ssr@13934
npm i https://pkg.pr.new/@vue/compiler-ssr@13934
yarn add https://pkg.pr.new/@vue/compiler-ssr@13934.tgz

@vue/compiler-vapor

pnpm add https://pkg.pr.new/@vue/compiler-vapor@13934
npm i https://pkg.pr.new/@vue/compiler-vapor@13934
yarn add https://pkg.pr.new/@vue/compiler-vapor@13934.tgz

@vue/reactivity

pnpm add https://pkg.pr.new/@vue/reactivity@13934
npm i https://pkg.pr.new/@vue/reactivity@13934
yarn add https://pkg.pr.new/@vue/reactivity@13934.tgz

@vue/runtime-core

pnpm add https://pkg.pr.new/@vue/runtime-core@13934
npm i https://pkg.pr.new/@vue/runtime-core@13934
yarn add https://pkg.pr.new/@vue/runtime-core@13934.tgz

@vue/runtime-dom

pnpm add https://pkg.pr.new/@vue/runtime-dom@13934
npm i https://pkg.pr.new/@vue/runtime-dom@13934
yarn add https://pkg.pr.new/@vue/runtime-dom@13934.tgz

@vue/runtime-vapor

pnpm add https://pkg.pr.new/@vue/runtime-vapor@13934
npm i https://pkg.pr.new/@vue/runtime-vapor@13934
yarn add https://pkg.pr.new/@vue/runtime-vapor@13934.tgz

@vue/server-renderer

pnpm add https://pkg.pr.new/@vue/server-renderer@13934
npm i https://pkg.pr.new/@vue/server-renderer@13934
yarn add https://pkg.pr.new/@vue/server-renderer@13934.tgz

@vue/shared

pnpm add https://pkg.pr.new/@vue/shared@13934
npm i https://pkg.pr.new/@vue/shared@13934
yarn add https://pkg.pr.new/@vue/shared@13934.tgz

vue

pnpm add https://pkg.pr.new/vue@13934
npm i https://pkg.pr.new/vue@13934
yarn add https://pkg.pr.new/vue@13934.tgz

@vue/compat

pnpm add https://pkg.pr.new/@vue/compat@13934
npm i https://pkg.pr.new/@vue/compat@13934
yarn add https://pkg.pr.new/@vue/compat@13934.tgz

commit: 59e7c77

@edison1105 edison1105 added version: minor scope: vapor related to vapor mode labels Sep 28, 2025
@edison1105

Copy link
Copy Markdown
Member

I've actually been planning to switch e2e tests to vitest browser mode too, but I haven't done it yet since vitest browser mode is still experimental. I have a question: after switching to vitest browser mode, does the e2e test execution time increase or decrease? If the difference isn't too significant, I think this PR is worthwhile.

@sheremet-va

Copy link
Copy Markdown
Author

have a question: after switching to vitest browser mode, does the e2e test execution time increase or decrease? If the difference isn't too significant, I think this PR is worthwhile.

The time is unpredictable with the previous approach for me, the first time it's ~2s, the second time ~1,5s. The browser mode runs for 2s (the MVC test is always 1,5s unlike with pupeteer where it's either 1,5s or 700ms). I think it might be because the previous setup was modifying the DOM directly (by setting input.value or doing a element.click() instead of using CDP which is slower). If we keep the previous implementation, I think the time will be the same, if not a little bit faster.

@edison1105

Copy link
Copy Markdown
Member

@sheremet-va
Sounds good to me. Let's move all e2e tests to vitest browser mode.

@sheremet-va

Copy link
Copy Markdown
Author

I will come back to this PR at some point. @edison1105 right now I am struggling with running unit tests in Vitest beta. It seems like BaseTransition.spec.ts is failing with the latest version (it's not the only test that fails) and I am not sure why. It seems like something was introduce in Vitest (probably related to spying) that is causing this. Can you help me debug it?

@edison1105

Copy link
Copy Markdown
Member

@sheremet-va
I'll take a look later

export function nextFrame() {
// this page is not same as Playwright's page
// how to wait for the next frame?
return page.evaluate(() => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@sheremet-va
I merged the latest code of minor into the current branch, but I encountered a problem and don't know how to solve it. this page is not same as Playwright's page. how to wait for the next frame? I couldn't find a solution in the vitest documentation.

Comment thread packages-private/vapor-e2e-test/__tests__/vdomInterop.spec.ts Outdated
Comment thread packages-private/vapor-e2e-test/__tests__/e2eUtils.ts Outdated
)
// comp leave
await css(btnSelector).click()
expect(css(containerSelector).element().innerHTML).toBe(

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Accessing element() is also not a good idea, checking toContainHTML is more resilient

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think it's better to leave the remaining test case refactoring work to you. I'll go and handle other PRS first.

@sheremet-va

Copy link
Copy Markdown
Author

The main issue I am having with VItest 4 is that unit tests are failing. Did you have a loot at them yet, @edison1105?

@edison1105

edison1105 commented Oct 23, 2025

Copy link
Copy Markdown
Member

@sheremet-va

// in vitest 3.2.4
const hook = vi.fn((el, done) => {})
test('hook length', () => {
  expect(hook.length).toBe(2) // true
})

// in vitest 4.x
const hook = vi.fn((el, done) => {})
test('hook length', () => {
  expect(hook.length).toBe(2) // should be 2 but got 0
})

The above difference is the cause of the BaseTransition.spec.ts failed. Internally, Transition uses hook.length to determine whether the animation has ended. If hook.length <= 1, done will be called.

const callAsyncHook = (
hook: Hook<(el: any, done: () => void) => void>,
args: [TransitionElement, () => void],
) => {
const done = args[1]
callHook(hook, args)
if (isArray(hook)) {
if (hook.every(hook => hook.length <= 1)) done()
} else if (hook.length <= 1) {
done()
}
}


Another test case (componentPublicInstance.spec.ts:348:28) failed. Simply change the 4 to 3. Refer to the comments in L344. (It equals 3 in jest) - You already fixed it via 7e56f8d.

// vitest does not cache the spy like jest do
const v3 = instanceProxy.toggle()
expect(v3).toEqual('b')
expect(spy).toHaveBeenCalled()
expect(getCalledTimes).toEqual(4)

@sheremet-va

sheremet-va commented Oct 23, 2025

Copy link
Copy Markdown
Author

Another test case (componentPublicInstance.spec.ts:348:28) failed. Simply change the 4 to 3. Refer to the comments in L344. (It equals 3 in jest) - You already fixed it via 7e56f8d.

That one is an expected breaking change, yeah.

The above difference is the cause of the BaseTransition.spec.ts failed. Internally, Transition uses hook.length to determine whether the animation has ended. If hook.length <= 1, done will be called.

Thank you so much for investigating, this is indeed a bug in Vitest!

Comment thread packages-private/vapor-e2e-test/__tests__/vdomInterop.spec.ts Outdated
@sheremet-va

Copy link
Copy Markdown
Author

Anything I can do to help out here?

@edison1105

Copy link
Copy Markdown
Member

@sheremet-va
I will finish the rest part next week and merge it

@edison1105
edison1105 force-pushed the test/rewrite-e2e-vapor-to-use-browser-mode branch from 6001dc7 to 3117cb5 Compare March 23, 2026 02:13
@edison1105
edison1105 merged commit 2f5189c into vuejs:minor Mar 23, 2026
14 of 15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scope: vapor related to vapor mode version: minor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants