mirror of
				https://github.com/microsoft/playwright.git
				synced 2025-06-26 21:40:17 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			307 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			307 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
/**
 | 
						|
 * Copyright (c) Microsoft Corporation.
 | 
						|
 *
 | 
						|
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
 * you may not use this file except in compliance with the License.
 | 
						|
 * You may obtain a copy of the License at
 | 
						|
 *
 | 
						|
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
 *
 | 
						|
 * Unless required by applicable law or agreed to in writing, software
 | 
						|
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
 * See the License for the specific language governing permissions and
 | 
						|
 * limitations under the License.
 | 
						|
 */
 | 
						|
 | 
						|
import fs from 'fs';
 | 
						|
import path from 'path';
 | 
						|
import { test, expect } from './playwright-test-fixtures';
 | 
						|
 | 
						|
const kRawReporterPath = path.join(__dirname, '..', '..', 'packages', 'playwright-test', 'lib', 'reporters', 'raw.js');
 | 
						|
 | 
						|
test('should generate raw report', async ({ runInlineTest }, testInfo) => {
 | 
						|
  const result = await runInlineTest({
 | 
						|
    'a.test.js': `
 | 
						|
      const { test } = pwt;
 | 
						|
      test('passes', async ({ page }, testInfo) => {});
 | 
						|
    `,
 | 
						|
  }, { reporter: 'dot,' + kRawReporterPath }, {}, { usesCustomOutputDir: true });
 | 
						|
  const json = JSON.parse(fs.readFileSync(testInfo.outputPath('test-results', 'report', 'project.report'), 'utf-8'));
 | 
						|
  expect(json.config).toBeTruthy();
 | 
						|
  expect(json.project).toBeTruthy();
 | 
						|
  expect(result.exitCode).toBe(0);
 | 
						|
});
 | 
						|
 | 
						|
test('should use project name', async ({ runInlineTest }, testInfo) => {
 | 
						|
  const result = await runInlineTest({
 | 
						|
    'playwright.config.ts': `
 | 
						|
      module.exports = {
 | 
						|
        projects: [{
 | 
						|
          name: 'project-name',
 | 
						|
          outputDir: 'output'
 | 
						|
        }]
 | 
						|
      }
 | 
						|
    `,
 | 
						|
    'a.test.js': `
 | 
						|
      const { test } = pwt;
 | 
						|
      test('passes', async ({ page }, testInfo) => {});
 | 
						|
    `,
 | 
						|
  }, { reporter: 'dot,' + kRawReporterPath }, {}, { usesCustomOutputDir: true });
 | 
						|
  const json = JSON.parse(fs.readFileSync(testInfo.outputPath('output', 'report', 'project-name.report'), 'utf-8'));
 | 
						|
  expect(json.project.name).toBe('project-name');
 | 
						|
  expect(result.exitCode).toBe(0);
 | 
						|
});
 | 
						|
 | 
						|
test('should save stdio', async ({ runInlineTest }, testInfo) => {
 | 
						|
  await runInlineTest({
 | 
						|
    'a.test.js': `
 | 
						|
      const { test } = pwt;
 | 
						|
      test('passes', async ({ page }, testInfo) => {
 | 
						|
        console.log('STDOUT');
 | 
						|
        process.stdout.write(Buffer.from([1, 2, 3]));
 | 
						|
        console.error('STDERR');
 | 
						|
        process.stderr.write(Buffer.from([4, 5, 6]));
 | 
						|
      });
 | 
						|
    `,
 | 
						|
  }, { reporter: 'dot,' + kRawReporterPath }, {}, { usesCustomOutputDir: true });
 | 
						|
  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).toEqual([
 | 
						|
    { name: 'stdout', contentType: 'text/plain', body: 'STDOUT\n' },
 | 
						|
    {
 | 
						|
      name: 'stdout',
 | 
						|
      contentType: 'application/octet-stream',
 | 
						|
      body: { data: [1, 2, 3], type: 'Buffer' }
 | 
						|
    },
 | 
						|
    { name: 'stderr', contentType: 'text/plain', body: 'STDERR\n' },
 | 
						|
    {
 | 
						|
      name: 'stderr',
 | 
						|
      contentType: 'application/octet-stream',
 | 
						|
      body: { data: [4, 5, 6], type: 'Buffer' }
 | 
						|
    }
 | 
						|
  ]);
 | 
						|
});
 | 
						|
 | 
						|
test('should save attachments', async ({ runInlineTest }, testInfo) => {
 | 
						|
  await runInlineTest({
 | 
						|
    'a.test.js': `
 | 
						|
      const { test } = pwt;
 | 
						|
      test('passes', async ({ page }, testInfo) => {
 | 
						|
        testInfo.attachments.push({
 | 
						|
          name: 'binary',
 | 
						|
          contentType: 'application/octet-stream',
 | 
						|
          body: Buffer.from([1,2,3])
 | 
						|
        });
 | 
						|
        testInfo.attachments.push({
 | 
						|
          name: 'text',
 | 
						|
          contentType: 'text/plain',
 | 
						|
          path: 'dummy-path'
 | 
						|
        });
 | 
						|
      });
 | 
						|
    `,
 | 
						|
  }, { reporter: 'dot,' + kRawReporterPath }, {}, { usesCustomOutputDir: true });
 | 
						|
  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('binary');
 | 
						|
  expect(Buffer.from(result.attachments[0].body, 'base64')).toEqual(Buffer.from([1,2,3]));
 | 
						|
  expect(result.attachments[1].name).toBe('text');
 | 
						|
  const path2 = result.attachments[1].path;
 | 
						|
  expect(path2).toBe('dummy-path');
 | 
						|
});
 | 
						|
 | 
						|
test(`testInfo.attach should save attachments via path`, async ({ runInlineTest }, testInfo) => {
 | 
						|
  await runInlineTest({
 | 
						|
    'a.test.js': `
 | 
						|
      const path = require('path');
 | 
						|
      const fs = require('fs');
 | 
						|
      const { test } = pwt;
 | 
						|
      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' });
 | 
						|
        // Forcibly remove the tmp file to ensure attach is actually automagically copying it
 | 
						|
        await fs.promises.unlink(tmpPath);
 | 
						|
      });
 | 
						|
 | 
						|
      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' });
 | 
						|
        // Forcibly remove the tmp file to ensure attach is actually automagically copying it
 | 
						|
        await fs.promises.unlink(tmpPath);
 | 
						|
      });
 | 
						|
 | 
						|
      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' });
 | 
						|
        // 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');
 | 
						|
        await fs.promises.writeFile(tmpPath, 'We <3 Playwright!');
 | 
						|
        await testInfo.attach(tmpPath, { name: 'example.this-extension-better-not-map-to-an-actual-mimetype' });
 | 
						|
        // Forcibly remove the tmp file to ensure attach is actually automagically copying it
 | 
						|
        await fs.promises.unlink(tmpPath);
 | 
						|
      });
 | 
						|
    `,
 | 
						|
  }, { reporter: 'dot,' + kRawReporterPath, workers: 1 }, {}, { usesCustomOutputDir: true });
 | 
						|
  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].contentType).toBe('application/json');
 | 
						|
    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[1].results[0];
 | 
						|
    expect(result.attachments[0].name).toBe('example.png');
 | 
						|
    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[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;
 | 
						|
    expect(p).toMatch(/[/\\]attachments[/\\]01a5667d100fac2200bf40cf43083fae0580c58e\.json$/);
 | 
						|
    const contents = fs.readFileSync(p);
 | 
						|
    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');
 | 
						|
    expect(result.attachments[0].contentType).toBe('application/octet-stream');
 | 
						|
    const p = result.attachments[0].path;
 | 
						|
    expect(p).toMatch(/[/\\]attachments[/\\]01a5667d100fac2200bf40cf43083fae0580c58e\.json$/);
 | 
						|
    const contents = fs.readFileSync(p);
 | 
						|
    expect(contents.toString()).toBe('We <3 Playwright!');
 | 
						|
  }
 | 
						|
});
 | 
						|
 | 
						|
test(`testInfo.attach should save attachments via inline attachment`, async ({ runInlineTest }, testInfo) => {
 | 
						|
  await runInlineTest({
 | 
						|
    'a.test.js': `
 | 
						|
      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('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('explicit contentType - string', async ({}, testInfo) => {
 | 
						|
        await testInfo.attach('We <3 Playwright!', 'example.json', { contentType: 'x-playwright/custom' });
 | 
						|
      });
 | 
						|
 | 
						|
      test('explicit contentType - Buffer', async ({}, testInfo) => {
 | 
						|
        await testInfo.attach(Buffer.from('We <3 Playwright!'), 'example.json', { contentType: 'x-playwright/custom' });
 | 
						|
      });
 | 
						|
  `,
 | 
						|
  }, { reporter: 'dot,' + kRawReporterPath, workers: 1 }, {}, { usesCustomOutputDir: true });
 | 
						|
  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].contentType).toBe('application/json');
 | 
						|
    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];
 | 
						|
    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];
 | 
						|
    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!'));
 | 
						|
  }
 | 
						|
});
 | 
						|
 | 
						|
test('dupe project names', async ({ runInlineTest }, testInfo) => {
 | 
						|
  await runInlineTest({
 | 
						|
    'playwright.config.ts': `
 | 
						|
      module.exports = {
 | 
						|
        projects: [
 | 
						|
          { name: 'project-name' },
 | 
						|
          { name: 'project-name' },
 | 
						|
          { name: 'project-name' },
 | 
						|
        ]
 | 
						|
      }
 | 
						|
    `,
 | 
						|
    'a.test.js': `
 | 
						|
      const { test } = pwt;
 | 
						|
      test('passes', async ({ page }, testInfo) => {});
 | 
						|
    `,
 | 
						|
  }, { reporter: 'dot,' + kRawReporterPath }, {}, { usesCustomOutputDir: true });
 | 
						|
  const files = fs.readdirSync(testInfo.outputPath('test-results', 'report'));
 | 
						|
  expect(new Set(files)).toEqual(new Set(['project-name.report', 'project-name-1.report', 'project-name-2.report']));
 | 
						|
});
 |