Open
Description
Version
1.47.0
Steps to reproduce
- Clone the minimal reproduced repo : https://github.com/nerdrun/playwright-unexpected-value-issue
- Run
pnpm i
andpnpm test-ct
- Check the
Unexpected Value
error message in the console
Expected behavior
Expected behaviour: Any type should be serialized when HooksConfig
value is passed to mount()
, however innerSerializeValue()
doesn't serialize function type
field.
store.ts
export type User = {
name: string;
age: number;
toUserString: () => string; // <== function type
};
export const useStore = defineStore('store', () => {
const user = ref<User>({ name: 'Steve', age: 20, toUserString: () => '' });
return {
user,
};
});
index.ts
import { createTestingPinia } from '@pinia/testing';
import { beforeMount } from '@playwright/experimental-ct-vue/hooks';
import { type StoreState } from 'pinia';
import { useStore } from '@/stores/store';
export type HooksConfig = {
store?: StoreState<ReturnType<typeof useStore>>;
};
beforeMount<HooksConfig>(async ({ app, hooksConfig }) => {
const pinia = createTestingPinia({
initialState: {
store: hooksConfig?.store,
},
stubActions: false,
createSpy(args) {
return () => args;
},
});
app.use(pinia);
});
TestPage.ct.ts
import { test, expect } from '@playwright/experimental-ct-vue';
import { type HooksConfig } from 'playwright';
import { type User } from '@/stores/store';
import TestPage from './TestPage.vue';
test.describe('<TestPage />', () => {
test('Test User', async ({ mount }) => {
const mockTestUser: User = {
name: 'Jackson',
age: 30,
toUserString: () => {
return 'Hello';
},
};
const component = await mount<HooksConfig>(TestPage, {
hooksConfig: { store: { user: mockTestUser } },
});
const name = component.getByTestId('name');
await expect(name).toHaveText('Jackson');
});
});
Actual behavior
Throw error message Unexpected value'
Additional context
I've debugged this issue and found out the part that caused the issue.
There is a innerSerializeValue()
that serializes arguments that is passed via mount()
in
...PATH/node_modules/.pnpm/@[email protected]_@[email protected]/node_modules/playwright-core/lib/protocol/serializers.js
There is no code to handle function
in the conditions.
function innerSerializeValue(value, handleSerializer, visitorInfo) {
const handle = handleSerializer(value);
if ('fallThrough' in handle) value = handle.fallThrough;else return handle;
if (typeof value === 'symbol') return {
v: 'undefined'
};
if (Object.is(value, undefined)) return {
v: 'undefined'
};
if (Object.is(value, null)) return {
v: 'null'
};
if (Object.is(value, NaN)) return {
v: 'NaN'
};
if (Object.is(value, Infinity)) return {
v: 'Infinity'
};
if (Object.is(value, -Infinity)) return {
v: '-Infinity'
};
if (Object.is(value, -0)) return {
v: '-0'
};
if (typeof value === 'boolean') return {
b: value
};
if (typeof value === 'number') return {
n: value
};
if (typeof value === 'string') return {
s: value
};
if (typeof value === 'bigint') return {
bi: value.toString()
};
if (isError(value)) return {
e: {
n: value.name,
m: value.message,
s: value.stack || ''
}
};
if (isDate(value)) return {
d: value.toJSON()
};
if (isURL(value)) return {
u: value.toJSON()
};
if (isRegExp(value)) return {
r: {
p: value.source,
f: value.flags
}
};
const id = visitorInfo.visited.get(value);
if (id) return {
ref: id
};
if (Array.isArray(value)) {
const a = [];
const id = ++visitorInfo.lastId;
visitorInfo.visited.set(value, id);
for (let i = 0; i < value.length; ++i) a.push(innerSerializeValue(value[i], handleSerializer, visitorInfo));
return {
a,
id
};
}
if (typeof value === 'object') {
const o = [];
const id = ++visitorInfo.lastId;
visitorInfo.visited.set(value, id);
for (const name of Object.keys(value)) o.push({
k: name,
v: innerSerializeValue(value[name], handleSerializer, visitorInfo)
});
return {
o,
id
};
}
throw new Error('Unexpected value');
}
Environment
System:
OS: macOS 14.6.1
CPU: (12) arm64 Apple M2 Pro
Memory: 81.16 MB / 16.00 GB
Binaries:
Node: 20.16.0 - ~/.asdf/installs/nodejs/20.16.0/bin.node
npm: 10.8.1 - ~/.asdf/plugins/nodejs/shims/npm
pnpm: 9.10.0 - /opt/homebrew/bin/pnpm
Languages:
Bash: 3.2.57 - /bin/bash
npmPackages:
@playwright/experimental-ct-vue: ^1.47.0 => 1.47.0