fix: do not pass unsafe `matcherResult` over IPC (#35565)
This commit is contained in:
parent
24699d6bd0
commit
adfad84bb8
|
@ -20,7 +20,6 @@ import { serializeCompilationCache } from '../transform/compilationCache';
|
||||||
|
|
||||||
import type { ConfigLocation, FullConfigInternal } from './config';
|
import type { ConfigLocation, FullConfigInternal } from './config';
|
||||||
import type { ReporterDescription, TestInfoError, TestStatus } from '../../types/test';
|
import type { ReporterDescription, TestInfoError, TestStatus } from '../../types/test';
|
||||||
import type { MatcherResultProperty } from '../matchers/matcherHint';
|
|
||||||
import type { SerializedCompilationCache } from '../transform/compilationCache';
|
import type { SerializedCompilationCache } from '../transform/compilationCache';
|
||||||
|
|
||||||
export type ConfigCLIOverrides = {
|
export type ConfigCLIOverrides = {
|
||||||
|
@ -83,9 +82,7 @@ export type AttachmentPayload = {
|
||||||
stepId?: string;
|
stepId?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TestInfoErrorImpl = TestInfoError & {
|
export type TestInfoErrorImpl = TestInfoError;
|
||||||
matcherResult?: MatcherResultProperty;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type TestEndPayload = {
|
export type TestEndPayload = {
|
||||||
testId: string;
|
testId: string;
|
||||||
|
|
|
@ -119,6 +119,13 @@ function sendMessageToParent(message: { method: string, params?: any }) {
|
||||||
try {
|
try {
|
||||||
process.send!(message);
|
process.send!(message);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
try {
|
||||||
|
// By default, the IPC messages are serialized as JSON.
|
||||||
|
JSON.stringify(message);
|
||||||
|
} catch {
|
||||||
|
// Always throw serialization errors.
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
// Can throw when closing.
|
// Can throw when closing.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,14 +14,10 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { ExpectError } from '../matchers/matcherHint';
|
|
||||||
import { serializeError } from '../util';
|
import { serializeError } from '../util';
|
||||||
|
|
||||||
import type { TestInfoErrorImpl } from '../common/ipc';
|
import type { TestInfoErrorImpl } from '../common/ipc';
|
||||||
|
|
||||||
export function testInfoError(error: Error | any): TestInfoErrorImpl {
|
export function testInfoError(error: Error | any): TestInfoErrorImpl {
|
||||||
const result = serializeError(error);
|
return serializeError(error);
|
||||||
if (error instanceof ExpectError)
|
|
||||||
result.matcherResult = error.matcherResult;
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -617,3 +617,48 @@ test('should fail when test.fail.only passes unexpectedly', async ({ runInlineTe
|
||||||
expect(result.output).not.toContain('test1 should not run');
|
expect(result.output).not.toContain('test1 should not run');
|
||||||
expect(result.output).not.toContain('test3 should not run');
|
expect(result.output).not.toContain('test3 should not run');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should serialize circular objects', async ({ runInlineTest }) => {
|
||||||
|
const result = await runInlineTest({
|
||||||
|
'one-failure.spec.ts': `
|
||||||
|
import { test, expect } from '@playwright/test';
|
||||||
|
test('circular dependency', () => {
|
||||||
|
const a = {};
|
||||||
|
a.b = a;
|
||||||
|
expect(1).toEqual(a);
|
||||||
|
});
|
||||||
|
`
|
||||||
|
});
|
||||||
|
expect(result.exitCode).toBe(1);
|
||||||
|
expect(result.passed).toBe(0);
|
||||||
|
expect(result.failed).toBe(1);
|
||||||
|
expect(result.output).toContain('Expected: {"b": [Circular]}');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should serialize BigInt', async ({ runInlineTest }) => {
|
||||||
|
const result = await runInlineTest({
|
||||||
|
'one-failure.spec.ts': `
|
||||||
|
import { test, expect } from '@playwright/test';
|
||||||
|
test('BigInt', () => {
|
||||||
|
expect(1).toEqual(1n);
|
||||||
|
});
|
||||||
|
`
|
||||||
|
});
|
||||||
|
expect(result.exitCode).toBe(1);
|
||||||
|
expect(result.failed).toBe(1);
|
||||||
|
expect(result.output).toContain('Expected: 1n');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should report serialization error', async ({ runInlineTest }) => {
|
||||||
|
const result = await runInlineTest({
|
||||||
|
'one-failure.spec.ts': `
|
||||||
|
import { test, expect } from '@playwright/test';
|
||||||
|
test('function', () => {
|
||||||
|
expect(1).toEqual({ a: () => {} });
|
||||||
|
});
|
||||||
|
`
|
||||||
|
});
|
||||||
|
expect(result.exitCode).toBe(1);
|
||||||
|
expect(result.passed).toBe(0);
|
||||||
|
expect(result.output).toContain('Expected: {\"a\": [Function a]}');
|
||||||
|
});
|
||||||
|
|
Loading…
Reference in New Issue