fix: unique resource names between shards (#23004)

This commit is contained in:
Yury Semikhatsky 2023-05-12 18:21:43 -07:00 committed by GitHub
parent 083d13a13d
commit 576d91fe80
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 75 additions and 1 deletions

View File

@ -32,6 +32,7 @@ type BlobReporterOptions = {
export class BlobReporter extends TeleReporterEmitter { export class BlobReporter extends TeleReporterEmitter {
private _messages: any[] = []; private _messages: any[] = [];
private _options: BlobReporterOptions; private _options: BlobReporterOptions;
private _salt: string;
private _copyFilePromises = new Set<Promise<void>>(); private _copyFilePromises = new Set<Promise<void>>();
private _outputDir!: string; private _outputDir!: string;
@ -40,6 +41,7 @@ export class BlobReporter extends TeleReporterEmitter {
constructor(options: BlobReporterOptions) { constructor(options: BlobReporterOptions) {
super(message => this._messages.push(message)); super(message => this._messages.push(message));
this._options = options; this._options = options;
this._salt = createGuid();
} }
override onBegin(config: FullConfig<{}, {}>, suite: Suite): void { override onBegin(config: FullConfig<{}, {}>, suite: Suite): void {
@ -64,7 +66,8 @@ export class BlobReporter extends TeleReporterEmitter {
return attachments.map(attachment => { return attachments.map(attachment => {
if (!attachment.path || !fs.statSync(attachment.path).isFile()) if (!attachment.path || !fs.statSync(attachment.path).isFile())
return attachment; return attachment;
const sha1 = calculateSha1(attachment.path); // Add run guid to avoid clashes between shards.
const sha1 = calculateSha1(attachment.path + this._salt);
const extension = mime.getExtension(attachment.contentType) || 'dat'; const extension = mime.getExtension(attachment.contentType) || 'dat';
const newPath = `resources/${sha1}.${extension}`; const newPath = `resources/${sha1}.${extension}`;
this._startCopyingFile(attachment.path, path.join(this._outputDir, newPath)); this._startCopyingFile(attachment.path, path.join(this._outputDir, newPath));

View File

@ -507,6 +507,77 @@ test('generate html with attachment urls', async ({ runInlineTest, mergeReports,
await expect(page.getByTestId('action-list').locator('div').filter({ hasText: /^expect\.toBe$/ })).toBeVisible(); await expect(page.getByTestId('action-list').locator('div').filter({ hasText: /^expect\.toBe$/ })).toBeVisible();
}); });
test('resource names should not clash between runs', async ({ runInlineTest, showReport, mergeReports, page }) => {
test.slow();
const reportDir = test.info().outputPath('blob-report');
const files = {
'playwright.config.ts': `
module.exports = {
reporter: [['blob', { outputDir: '${reportDir.replace(/\\/g, '/')}' }]]
};
`,
'a.test.js': `
import { test, expect } from '@playwright/test';
import fs from 'fs';
import path from 'path';
test('first', async ({}) => {
const attachmentPath = path.join(test.info().config.rootDir, 'foo.txt');
fs.writeFileSync(attachmentPath, 'hello!');
test.info().attachments.push({ name: 'file-attachment', path: attachmentPath, contentType: 'text/plain' });
});
`,
'b.test.js': `
import { test, expect } from '@playwright/test';
import fs from 'fs';
import path from 'path';
test('failing 2', async ({}) => {
const attachmentPath = path.join(test.info().config.rootDir, 'foo.txt');
fs.writeFileSync(attachmentPath, 'bye!');
test.info().attachments.push({ name: 'file-attachment', path: attachmentPath, contentType: 'text/plain' });
});
`
};
await runInlineTest(files, { shard: `1/2` });
await runInlineTest(files, { shard: `2/2` });
const reportFiles = await fs.promises.readdir(reportDir);
reportFiles.sort();
expect(reportFiles).toEqual([expect.stringMatching(/report-1-of-2.*.jsonl/), expect.stringMatching(/report-2-of-2.*.jsonl/), 'resources']);
const { exitCode } = await mergeReports(reportDir, {}, { additionalArgs: ['--reporter', 'html'] });
expect(exitCode).toBe(0);
await showReport();
// Check first attachment content.
{
await page.getByText('first').click();
await expect(page.getByText('file-attachment')).toBeVisible();
const popupPromise = page.waitForEvent('popup');
await page.getByText('file-attachment').click();
const popup = await popupPromise;
await expect(popup.locator('body')).toHaveText('hello!');
await popup.close();
await page.goBack();
}
// Check second attachment content.
{
await page.getByText('failing 2').click();
await expect(page.getByText('file-attachment')).toBeVisible();
const popupPromise = page.waitForEvent('popup');
await page.getByText('file-attachment').click();
const popup = await popupPromise;
await expect(popup.locator('body')).toHaveText('bye!');
await popup.close();
await page.goBack();
}
});
test('multiple output reports', async ({ runInlineTest, mergeReports, showReport, page }) => { test('multiple output reports', async ({ runInlineTest, mergeReports, showReport, page }) => {
test.slow(); test.slow();
const reportDir = test.info().outputPath('blob-report'); const reportDir = test.info().outputPath('blob-report');