mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
fix(test runner): testInfo.attach api review changes (#11211)
Remove overload, require name, merge options.
This commit is contained in:
parent
1857a16381
commit
3ecac56cc0
@ -40,10 +40,11 @@ Learn more about [test annotations](./test-annotations.md).
|
||||
|
||||
The list of files or buffers attached to the current test. Some reporters show test attachments.
|
||||
|
||||
To safely add a file from disk as an attachment, please use [`method: TestInfo.attach#1`] instead of directly pushing onto this array. For inline attachments, use [`method: TestInfo.attach#1`].
|
||||
To add an attachment, use [`method: TestInfo.attach`] instead of directly pushing onto this array.
|
||||
|
||||
## method: TestInfo.attach#1
|
||||
Attach a file from disk to the current test. Some reporters show test attachments. The [`option: name`] and [`option: contentType`] will be inferred by default from the [`param: path`], but you can optionally override either of these.
|
||||
## method: TestInfo.attach
|
||||
|
||||
Attach a value or a file from disk to the current test. Some reporters show test attachments. Either [`option: path`] or [`option: body`] must be specified, but not both.
|
||||
|
||||
For example, you can attach a screenshot to the test:
|
||||
|
||||
@ -52,15 +53,8 @@ const { test, expect } = require('@playwright/test');
|
||||
|
||||
test('basic test', async ({ page }, testInfo) => {
|
||||
await page.goto('https://playwright.dev');
|
||||
|
||||
// Capture a screenshot and attach it.
|
||||
const path = testInfo.outputPath('screenshot.png');
|
||||
await page.screenshot({ path });
|
||||
await testInfo.attach(path);
|
||||
// Optionally override the name.
|
||||
await testInfo.attach(path, { name: 'example.png' });
|
||||
// Optionally override the contentType.
|
||||
await testInfo.attach(path, { name: 'example.custom-file', contentType: 'x-custom-content-type' });
|
||||
const screenshot = await page.screenshot();
|
||||
await testInfo.attach('screenshot', { body: screenshot, contentType: 'image/png' });
|
||||
});
|
||||
```
|
||||
|
||||
@ -69,15 +63,8 @@ import { test, expect } from '@playwright/test';
|
||||
|
||||
test('basic test', async ({ page }, testInfo) => {
|
||||
await page.goto('https://playwright.dev');
|
||||
|
||||
// Capture a screenshot and attach it.
|
||||
const path = testInfo.outputPath('screenshot.png');
|
||||
await page.screenshot({ path });
|
||||
await testInfo.attach(path);
|
||||
// Optionally override the name.
|
||||
await testInfo.attach(path, { name: 'example.png' });
|
||||
// Optionally override the contentType.
|
||||
await testInfo.attach(path, { name: 'example.custom-file', contentType: 'x-custom-content-type' });
|
||||
const screenshot = await page.screenshot();
|
||||
await testInfo.attach('screenshot', { body: screenshot, contentType: 'image/png' });
|
||||
});
|
||||
```
|
||||
|
||||
@ -89,7 +76,7 @@ const { test, expect } = require('@playwright/test');
|
||||
test('basic test', async ({}, testInfo) => {
|
||||
const { download } = require('./my-custom-helpers');
|
||||
const tmpPath = await download('a');
|
||||
await testInfo.attach(tmpPath, { name: 'example.json' });
|
||||
await testInfo.attach('downloaded', { path: tmpPath });
|
||||
});
|
||||
```
|
||||
|
||||
@ -99,38 +86,28 @@ import { test, expect } from '@playwright/test';
|
||||
test('basic test', async ({}, testInfo) => {
|
||||
const { download } = require('./my-custom-helpers');
|
||||
const tmpPath = await download('a');
|
||||
await testInfo.attach(tmpPath, { name: 'example.json' });
|
||||
await testInfo.attach('downloaded', { path: tmpPath });
|
||||
});
|
||||
```
|
||||
|
||||
:::note
|
||||
[`method: TestInfo.attach#1`] automatically takes care of copying attachments to a
|
||||
location that is accessible to reporters, even if you were to delete the attachment
|
||||
[`method: TestInfo.attach`] automatically takes care of copying attached files to a
|
||||
location that is accessible to reporters. You can safely remove the attachment
|
||||
after awaiting the attach call.
|
||||
:::
|
||||
|
||||
### param: TestInfo.attach#1.path
|
||||
- `path` <[string]> Path on the filesystem to the attached file.
|
||||
|
||||
### option: TestInfo.attach#1.name
|
||||
- `name` <[void]|[string]> Optional attachment name. If omitted, this will be inferred from [`param: path`].
|
||||
|
||||
### option: TestInfo.attach#1.contentType
|
||||
- `contentType` <[void]|[string]> Optional content type of this attachment to properly present in the report, for example `'application/json'` or `'image/png'`. If omitted, this falls back to an inferred type based on the [`param: name`] (if set) or [`param: path`]'s extension; it will be set to `application/octet-stream` if the type cannot be inferred from the file extension.
|
||||
|
||||
|
||||
## method: TestInfo.attach#2
|
||||
|
||||
Attach data to the current test, either a `string` or a `Buffer`. Some reporters show test attachments.
|
||||
|
||||
### param: TestInfo.attach#2.body
|
||||
- `body` <[string]|[Buffer]> Attachment body.
|
||||
|
||||
### param: TestInfo.attach#2.name
|
||||
### param: TestInfo.attach.name
|
||||
- `name` <[string]> Attachment name.
|
||||
|
||||
### option: TestInfo.attach#2.contentType
|
||||
- `contentType` <[void]|[string]> Optional content type of this attachment to properly present in the report, for example `'application/json'` or `'application/xml'`. If omitted, this falls back to an inferred type based on the [`param: name`]'s extension; if the type cannot be inferred from the name's extension, it will be set to `text/plain` (if [`param: body`] is a `string`) or `application/octet-stream` (if [`param: body`] is a `Buffer`).
|
||||
### option: TestInfo.attach.body
|
||||
- `body` <[string]|[Buffer]> Attachment body. Mutually exclusive with [`option: path`].
|
||||
|
||||
### option: TestInfo.attach.contentType
|
||||
- `contentType` <[void]|[string]> Optional content type of this attachment to properly present in the report, for example `'application/json'` or `'image/png'`. If omitted, content type is inferred based on the [`option: path`], or defaults to `text/plain` for [string] attachments and `application/octet-stream` for [Buffer] attachments.
|
||||
|
||||
### option: TestInfo.attach.path
|
||||
- `path` <[string]> Path on the filesystem to the attached file. Mutually exclusive with [`option: body`].
|
||||
|
||||
|
||||
## property: TestInfo.column
|
||||
- type: <[int]>
|
||||
|
||||
@ -264,39 +264,20 @@ export class WorkerRunner extends EventEmitter {
|
||||
expectedStatus: test.expectedStatus,
|
||||
annotations: [],
|
||||
attachments: [],
|
||||
attach: async (...args) => {
|
||||
const [ pathOrBody, nameOrFileOptions, inlineOptions ] = args as [string | Buffer, string | { contentType?: string, name?: string} | undefined, { contentType?: string } | undefined];
|
||||
let attachment: { name: string, contentType: string, body?: Buffer, path?: string } | undefined;
|
||||
if (typeof nameOrFileOptions === 'string') { // inline attachment
|
||||
const body = pathOrBody;
|
||||
const name = nameOrFileOptions;
|
||||
|
||||
attachment = {
|
||||
name,
|
||||
contentType: inlineOptions?.contentType ?? (mime.getType(name) || (typeof body === 'string' ? 'text/plain' : 'application/octet-stream')),
|
||||
body: typeof body === 'string' ? Buffer.from(body) : body,
|
||||
};
|
||||
} else { // path based attachment
|
||||
const options = nameOrFileOptions;
|
||||
const thePath = pathOrBody as string;
|
||||
const name = options?.name ?? path.basename(thePath);
|
||||
attachment = {
|
||||
name,
|
||||
path: thePath,
|
||||
contentType: options?.contentType ?? (mime.getType(name) || 'application/octet-stream')
|
||||
};
|
||||
}
|
||||
|
||||
const tmpAttachment = { ...attachment };
|
||||
if (attachment.path) {
|
||||
const hash = await calculateFileSha1(attachment.path);
|
||||
const dest = testInfo.outputPath('attachments', hash + path.extname(attachment.path));
|
||||
attach: async (name: string, options: { path?: string, body?: string | Buffer, contentType?: string } = {}) => {
|
||||
if ((options.path !== undefined ? 1 : 0) + (options.body !== undefined ? 1 : 0) !== 1)
|
||||
throw new Error(`Exactly one of "path" and "body" must be specified`);
|
||||
if (options.path) {
|
||||
const hash = await calculateFileSha1(options.path);
|
||||
const dest = testInfo.outputPath('attachments', hash + path.extname(options.path));
|
||||
await fs.promises.mkdir(path.dirname(dest), { recursive: true });
|
||||
await fs.promises.copyFile(attachment.path, dest);
|
||||
tmpAttachment.path = dest;
|
||||
await fs.promises.copyFile(options.path, dest);
|
||||
const contentType = options.contentType ?? (mime.getType(path.basename(options.path)) || 'application/octet-stream');
|
||||
testInfo.attachments.push({ name, contentType, path: dest });
|
||||
} else {
|
||||
const contentType = options.contentType ?? (typeof options.body === 'string' ? 'text/plain' : 'application/octet-stream');
|
||||
testInfo.attachments.push({ name, contentType, body: typeof options.body === 'string' ? Buffer.from(options.body) : options.body });
|
||||
}
|
||||
|
||||
testInfo.attachments.push(tmpAttachment);
|
||||
},
|
||||
duration: 0,
|
||||
status: 'passed',
|
||||
|
||||
39
packages/playwright-test/types/test.d.ts
vendored
39
packages/playwright-test/types/test.d.ts
vendored
@ -1389,15 +1389,14 @@ export interface TestInfo {
|
||||
/**
|
||||
* The list of files or buffers attached to the current test. Some reporters show test attachments.
|
||||
*
|
||||
* To safely add a file from disk as an attachment, please use
|
||||
* [testInfo.attach(path[, options])](https://playwright.dev/docs/api/class-testinfo#test-info-attach-1) instead of
|
||||
* directly pushing onto this array. For inline attachments, use
|
||||
* [testInfo.attach(path[, options])](https://playwright.dev/docs/api/class-testinfo#test-info-attach-1).
|
||||
* To add an attachment, use
|
||||
* [testInfo.attach(name[, options])](https://playwright.dev/docs/api/class-testinfo#test-info-attach) instead of directly
|
||||
* pushing onto this array.
|
||||
*/
|
||||
attachments: { name: string, path?: string, body?: Buffer, contentType: string }[];
|
||||
/**
|
||||
* Attach a file from disk to the current test. Some reporters show test attachments. The `name` and `contentType` will be
|
||||
* inferred by default from the `path`, but you can optionally override either of these.
|
||||
* Attach a value or a file from disk to the current test. Some reporters show test attachments. Either `path` or `body`
|
||||
* must be specified, but not both.
|
||||
*
|
||||
* For example, you can attach a screenshot to the test:
|
||||
*
|
||||
@ -1406,15 +1405,8 @@ export interface TestInfo {
|
||||
*
|
||||
* test('basic test', async ({ page }, testInfo) => {
|
||||
* await page.goto('https://playwright.dev');
|
||||
*
|
||||
* // Capture a screenshot and attach it.
|
||||
* const path = testInfo.outputPath('screenshot.png');
|
||||
* await page.screenshot({ path });
|
||||
* await testInfo.attach(path);
|
||||
* // Optionally override the name.
|
||||
* await testInfo.attach(path, { name: 'example.png' });
|
||||
* // Optionally override the contentType.
|
||||
* await testInfo.attach(path, { name: 'example.custom-file', contentType: 'x-custom-content-type' });
|
||||
* const screenshot = await page.screenshot();
|
||||
* await testInfo.attach('screenshot', { body: screenshot, contentType: 'image/png' });
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
@ -1426,24 +1418,17 @@ export interface TestInfo {
|
||||
* test('basic test', async ({}, testInfo) => {
|
||||
* const { download } = require('./my-custom-helpers');
|
||||
* const tmpPath = await download('a');
|
||||
* await testInfo.attach(tmpPath, { name: 'example.json' });
|
||||
* await testInfo.attach('downloaded', { path: tmpPath });
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* > NOTE: [testInfo.attach(path[, options])](https://playwright.dev/docs/api/class-testinfo#test-info-attach-1)
|
||||
* automatically takes care of copying attachments to a location that is accessible to reporters, even if you were to
|
||||
* delete the attachment after awaiting the attach call.
|
||||
* @param path
|
||||
* @param options
|
||||
*/
|
||||
attach(path: string, options?: { contentType?: string, name?: string}): Promise<void>;
|
||||
/**
|
||||
* Attach data to the current test, either a `string` or a `Buffer`. Some reporters show test attachments.
|
||||
* @param body
|
||||
* > NOTE: [testInfo.attach(name[, options])](https://playwright.dev/docs/api/class-testinfo#test-info-attach)
|
||||
* automatically takes care of copying attached files to a location that is accessible to reporters. You can safely remove
|
||||
* the attachment after awaiting the attach call.
|
||||
* @param name
|
||||
* @param options
|
||||
*/
|
||||
attach(body: string | Buffer, name: string, options?: { contentType?: string }): Promise<void>;
|
||||
attach(name: string, options?: { contentType?: string, path?: string, body?: string | Buffer }): Promise<void>;
|
||||
/**
|
||||
* Specifies a unique repeat index when running in "repeat each" mode. This mode is enabled by passing `--repeat-each` to
|
||||
* the [command line](https://playwright.dev/docs/test-cli).
|
||||
|
||||
@ -81,33 +81,25 @@ test('render trace attachment', async ({ runInlineTest }) => {
|
||||
});
|
||||
|
||||
|
||||
test(`testInfo.attach throws an error when attaching a non-existent attachment`, async ({ runInlineTest }) => {
|
||||
test(`testInfo.attach errors`, async ({ runInlineTest }) => {
|
||||
const result = await runInlineTest({
|
||||
'a.test.js': `
|
||||
const { test } = pwt;
|
||||
test('all options specified', async ({}, testInfo) => {
|
||||
await testInfo.attach('non-existent-path-all-options', { contentType: 'text/plain', name: 'foo.txt'});
|
||||
test('fail1', async ({}, testInfo) => {
|
||||
await testInfo.attach('name', { path: 'foo.txt' });
|
||||
});
|
||||
|
||||
test('no options specified', async ({}, testInfo) => {
|
||||
await testInfo.attach('non-existent-path-no-options');
|
||||
test('fail2', async ({}, testInfo) => {
|
||||
await testInfo.attach('name', { path: 'foo.txt', body: 'bar' });
|
||||
});
|
||||
|
||||
test('partial options - contentType', async ({}, testInfo) => {
|
||||
await testInfo.attach('non-existent-path-partial-options-content-type', { contentType: 'text/plain'});
|
||||
});
|
||||
|
||||
test('partial options - name', async ({}, testInfo) => {
|
||||
await testInfo.attach('non-existent-path-partial-options-name', { name: 'foo.txt'});
|
||||
test('fail3', async ({}, testInfo) => {
|
||||
await testInfo.attach('name', {});
|
||||
});
|
||||
`,
|
||||
}, { reporter: 'line', workers: 1 });
|
||||
const text = stripAscii(result.output).replace(/\\/g, '/');
|
||||
expect(text).toMatch(/Error: ENOENT: no such file or directory, open '.*non-existent-path-all-options.*'/);
|
||||
expect(text).toMatch(/Error: ENOENT: no such file or directory, open '.*non-existent-path-no-options.*'/);
|
||||
expect(text).toMatch(/Error: ENOENT: no such file or directory, open '.*non-existent-path-partial-options-content-type.*'/);
|
||||
expect(text).toMatch(/Error: ENOENT: no such file or directory, open '.*non-existent-path-partial-options-name.*'/);
|
||||
expect(text).toMatch(/Error: ENOENT: no such file or directory, open '.*foo.txt.*'/);
|
||||
expect(text).toContain(`Exactly one of "path" and "body" must be specified`);
|
||||
expect(result.passed).toBe(0);
|
||||
expect(result.failed).toBe(4);
|
||||
expect(result.failed).toBe(3);
|
||||
expect(result.exitCode).toBe(1);
|
||||
});
|
||||
|
||||
@ -119,15 +119,7 @@ test(`testInfo.attach should save attachments via path`, async ({ runInlineTest
|
||||
test('infer contentType from path', async ({}, testInfo) => {
|
||||
const tmpPath = testInfo.outputPath('example.json');
|
||||
await fs.promises.writeFile(tmpPath, 'We <3 Playwright!');
|
||||
await testInfo.attach(tmpPath);
|
||||
// Forcibly remove the tmp file to ensure attach is actually automagically copying it
|
||||
await fs.promises.unlink(tmpPath);
|
||||
});
|
||||
|
||||
test('infer contentType from name (over extension)', async ({}, testInfo) => {
|
||||
const tmpPath = testInfo.outputPath('example.json');
|
||||
await fs.promises.writeFile(tmpPath, 'We <3 Playwright!');
|
||||
await testInfo.attach(tmpPath, { name: 'example.png' });
|
||||
await testInfo.attach('foo', { path: tmpPath });
|
||||
// Forcibly remove the tmp file to ensure attach is actually automagically copying it
|
||||
await fs.promises.unlink(tmpPath);
|
||||
});
|
||||
@ -135,7 +127,7 @@ test(`testInfo.attach should save attachments via path`, async ({ runInlineTest
|
||||
test('explicit contentType (over extension)', async ({}, testInfo) => {
|
||||
const tmpPath = testInfo.outputPath('example.json');
|
||||
await fs.promises.writeFile(tmpPath, 'We <3 Playwright!');
|
||||
await testInfo.attach(tmpPath, { contentType: 'image/png' });
|
||||
await testInfo.attach('foo', { path: tmpPath, contentType: 'image/png' });
|
||||
// Forcibly remove the tmp file to ensure attach is actually automagically copying it
|
||||
await fs.promises.unlink(tmpPath);
|
||||
});
|
||||
@ -143,15 +135,15 @@ test(`testInfo.attach should save attachments via path`, async ({ runInlineTest
|
||||
test('explicit contentType (over extension and name)', async ({}, testInfo) => {
|
||||
const tmpPath = testInfo.outputPath('example.json');
|
||||
await fs.promises.writeFile(tmpPath, 'We <3 Playwright!');
|
||||
await testInfo.attach(tmpPath, { name: 'example.png', contentType: 'x-playwright/custom' });
|
||||
await testInfo.attach('example.png', { path: tmpPath, contentType: 'x-playwright/custom' });
|
||||
// Forcibly remove the tmp file to ensure attach is actually automagically copying it
|
||||
await fs.promises.unlink(tmpPath);
|
||||
});
|
||||
|
||||
test('fallback contentType', async ({}, testInfo) => {
|
||||
const tmpPath = testInfo.outputPath('example.json');
|
||||
const tmpPath = testInfo.outputPath('example.this-extension-better-not-map-to-an-actual-mimetype');
|
||||
await fs.promises.writeFile(tmpPath, 'We <3 Playwright!');
|
||||
await testInfo.attach(tmpPath, { name: 'example.this-extension-better-not-map-to-an-actual-mimetype' });
|
||||
await testInfo.attach('foo', { path: tmpPath });
|
||||
// Forcibly remove the tmp file to ensure attach is actually automagically copying it
|
||||
await fs.promises.unlink(tmpPath);
|
||||
});
|
||||
@ -160,7 +152,7 @@ test(`testInfo.attach should save attachments via path`, async ({ runInlineTest
|
||||
const json = JSON.parse(fs.readFileSync(testInfo.outputPath('test-results', 'report', 'project.report'), 'utf-8'));
|
||||
{
|
||||
const result = json.suites[0].tests[0].results[0];
|
||||
expect(result.attachments[0].name).toBe('example.json');
|
||||
expect(result.attachments[0].name).toBe('foo');
|
||||
expect(result.attachments[0].contentType).toBe('application/json');
|
||||
const p = result.attachments[0].path;
|
||||
expect(p).toMatch(/[/\\]attachments[/\\]01a5667d100fac2200bf40cf43083fae0580c58e\.json$/);
|
||||
@ -169,7 +161,7 @@ test(`testInfo.attach should save attachments via path`, async ({ runInlineTest
|
||||
}
|
||||
{
|
||||
const result = json.suites[0].tests[1].results[0];
|
||||
expect(result.attachments[0].name).toBe('example.png');
|
||||
expect(result.attachments[0].name).toBe('foo');
|
||||
expect(result.attachments[0].contentType).toBe('image/png');
|
||||
const p = result.attachments[0].path;
|
||||
expect(p).toMatch(/[/\\]attachments[/\\]01a5667d100fac2200bf40cf43083fae0580c58e\.json$/);
|
||||
@ -178,15 +170,6 @@ test(`testInfo.attach should save attachments via path`, async ({ runInlineTest
|
||||
}
|
||||
{
|
||||
const result = json.suites[0].tests[2].results[0];
|
||||
expect(result.attachments[0].name).toBe('example.json');
|
||||
expect(result.attachments[0].contentType).toBe('image/png');
|
||||
const p = result.attachments[0].path;
|
||||
expect(p).toMatch(/[/\\]attachments[/\\]01a5667d100fac2200bf40cf43083fae0580c58e\.json$/);
|
||||
const contents = fs.readFileSync(p);
|
||||
expect(contents.toString()).toBe('We <3 Playwright!');
|
||||
}
|
||||
{
|
||||
const result = json.suites[0].tests[3].results[0];
|
||||
expect(result.attachments[0].name).toBe('example.png');
|
||||
expect(result.attachments[0].contentType).toBe('x-playwright/custom');
|
||||
const p = result.attachments[0].path;
|
||||
@ -195,11 +178,11 @@ test(`testInfo.attach should save attachments via path`, async ({ runInlineTest
|
||||
expect(contents.toString()).toBe('We <3 Playwright!');
|
||||
}
|
||||
{
|
||||
const result = json.suites[0].tests[4].results[0];
|
||||
expect(result.attachments[0].name).toBe('example.this-extension-better-not-map-to-an-actual-mimetype');
|
||||
const result = json.suites[0].tests[3].results[0];
|
||||
expect(result.attachments[0].name).toBe('foo');
|
||||
expect(result.attachments[0].contentType).toBe('application/octet-stream');
|
||||
const p = result.attachments[0].path;
|
||||
expect(p).toMatch(/[/\\]attachments[/\\]01a5667d100fac2200bf40cf43083fae0580c58e\.json$/);
|
||||
expect(p).toMatch(/[/\\]attachments[/\\]01a5667d100fac2200bf40cf43083fae0580c58e\.this-extension-better-not-map-to-an-actual-mimetype$/);
|
||||
const contents = fs.readFileSync(p);
|
||||
expect(contents.toString()).toBe('We <3 Playwright!');
|
||||
}
|
||||
@ -211,32 +194,20 @@ test(`testInfo.attach should save attachments via inline attachment`, async ({ r
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const { test } = pwt;
|
||||
test('infer contentType - string', async ({}, testInfo) => {
|
||||
await testInfo.attach('We <3 Playwright!', 'example.json');
|
||||
test('default contentType - string', async ({}, testInfo) => {
|
||||
await testInfo.attach('example.json', { body: 'We <3 Playwright!' });
|
||||
});
|
||||
|
||||
test('infer contentType - Buffer', async ({}, testInfo) => {
|
||||
await testInfo.attach(Buffer.from('We <3 Playwright!'), 'example.json');
|
||||
});
|
||||
|
||||
test('fallback contentType - string', async ({}, testInfo) => {
|
||||
await testInfo.attach('We <3 Playwright!', 'example.this-extension-better-not-map-to-an-actual-mimetype');
|
||||
});
|
||||
|
||||
test('fallback contentType - Buffer', async ({}, testInfo) => {
|
||||
await testInfo.attach(Buffer.from('We <3 Playwright!'), 'example.this-extension-better-not-map-to-an-actual-mimetype');
|
||||
});
|
||||
|
||||
test('fallback contentType - no extension', async ({}, testInfo) => {
|
||||
await testInfo.attach('We <3 Playwright!', 'example');
|
||||
test('default contentType - Buffer', async ({}, testInfo) => {
|
||||
await testInfo.attach('example.json', { body: Buffer.from('We <3 Playwright!') });
|
||||
});
|
||||
|
||||
test('explicit contentType - string', async ({}, testInfo) => {
|
||||
await testInfo.attach('We <3 Playwright!', 'example.json', { contentType: 'x-playwright/custom' });
|
||||
await testInfo.attach('example.json', { body: 'We <3 Playwright!', contentType: 'x-playwright/custom' });
|
||||
});
|
||||
|
||||
test('explicit contentType - Buffer', async ({}, testInfo) => {
|
||||
await testInfo.attach(Buffer.from('We <3 Playwright!'), 'example.json', { contentType: 'x-playwright/custom' });
|
||||
await testInfo.attach('example.json', { body: Buffer.from('We <3 Playwright!'), contentType: 'x-playwright/custom' });
|
||||
});
|
||||
`,
|
||||
}, { reporter: 'dot,' + kRawReporterPath, workers: 1 }, {}, { usesCustomOutputDir: true });
|
||||
@ -244,41 +215,23 @@ test(`testInfo.attach should save attachments via inline attachment`, async ({ r
|
||||
{
|
||||
const result = json.suites[0].tests[0].results[0];
|
||||
expect(result.attachments[0].name).toBe('example.json');
|
||||
expect(result.attachments[0].contentType).toBe('application/json');
|
||||
expect(result.attachments[0].contentType).toBe('text/plain');
|
||||
expect(Buffer.from(result.attachments[0].body, 'base64')).toEqual(Buffer.from('We <3 Playwright!'));
|
||||
}
|
||||
{
|
||||
const result = json.suites[0].tests[1].results[0];
|
||||
expect(result.attachments[0].name).toBe('example.json');
|
||||
expect(result.attachments[0].contentType).toBe('application/json');
|
||||
expect(Buffer.from(result.attachments[0].body, 'base64')).toEqual(Buffer.from('We <3 Playwright!'));
|
||||
}
|
||||
{
|
||||
const result = json.suites[0].tests[2].results[0];
|
||||
expect(result.attachments[0].name).toBe('example.this-extension-better-not-map-to-an-actual-mimetype');
|
||||
expect(result.attachments[0].contentType).toBe('text/plain');
|
||||
expect(Buffer.from(result.attachments[0].body, 'base64')).toEqual(Buffer.from('We <3 Playwright!'));
|
||||
}
|
||||
{
|
||||
const result = json.suites[0].tests[3].results[0];
|
||||
expect(result.attachments[0].name).toBe('example.this-extension-better-not-map-to-an-actual-mimetype');
|
||||
expect(result.attachments[0].contentType).toBe('application/octet-stream');
|
||||
expect(Buffer.from(result.attachments[0].body, 'base64')).toEqual(Buffer.from('We <3 Playwright!'));
|
||||
}
|
||||
{
|
||||
const result = json.suites[0].tests[4].results[0];
|
||||
expect(result.attachments[0].name).toBe('example');
|
||||
expect(result.attachments[0].contentType).toBe('text/plain');
|
||||
expect(Buffer.from(result.attachments[0].body, 'base64')).toEqual(Buffer.from('We <3 Playwright!'));
|
||||
}
|
||||
{
|
||||
const result = json.suites[0].tests[5].results[0];
|
||||
const result = json.suites[0].tests[2].results[0];
|
||||
expect(result.attachments[0].name).toBe('example.json');
|
||||
expect(result.attachments[0].contentType).toBe('x-playwright/custom');
|
||||
expect(Buffer.from(result.attachments[0].body, 'base64')).toEqual(Buffer.from('We <3 Playwright!'));
|
||||
}
|
||||
{
|
||||
const result = json.suites[0].tests[6].results[0];
|
||||
const result = json.suites[0].tests[3].results[0];
|
||||
expect(result.attachments[0].name).toBe('example.json');
|
||||
expect(result.attachments[0].contentType).toBe('x-playwright/custom');
|
||||
expect(Buffer.from(result.attachments[0].body, 'base64')).toEqual(Buffer.from('We <3 Playwright!'));
|
||||
|
||||
3
utils/generate_types/overrides-test.d.ts
vendored
3
utils/generate_types/overrides-test.d.ts
vendored
@ -204,8 +204,7 @@ export interface TestInfo {
|
||||
timeout: number;
|
||||
annotations: { type: string, description?: string }[];
|
||||
attachments: { name: string, path?: string, body?: Buffer, contentType: string }[];
|
||||
attach(path: string, options?: { contentType?: string, name?: string}): Promise<void>;
|
||||
attach(body: string | Buffer, name: string, options?: { contentType?: string }): Promise<void>;
|
||||
attach(name: string, options?: { contentType?: string, path?: string, body?: string | Buffer }): Promise<void>;
|
||||
repeatEachIndex: number;
|
||||
retry: number;
|
||||
duration: number;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user