Skip to content

Commit

Permalink
Refactor how source test file paths are handled.
Browse files Browse the repository at this point in the history
- new file `constants.js` to hold the source paths for the test files.
- call `createTestFile` by default and provide path.
- refactor the createTestFile method to use better variable names.

Revise behavior when hook fails.

Revise environment behavior again.
- set the `hookFailed` attribute to true if hook failure is experienced.
- add clause at `test_start` event to check for hook failure, and if detected, mark rest of the test cases as failed.

Rebase.
  • Loading branch information
worldomonation committed Sep 9, 2021
1 parent 1918804 commit eedb093
Show file tree
Hide file tree
Showing 15 changed files with 98 additions and 92 deletions.
4 changes: 1 addition & 3 deletions packages/calypso-e2e/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@ import * as BrowserManager from './browser-manager';
import * as DataHelper from './data-helper';
import * as ElementHelper from './element-helper';
import * as MediaHelper from './media-helper';
export type { TestFile } from './media-helper';

export { BrowserHelper, BrowserManager, MediaHelper, DataHelper, ElementHelper };

export * from './lib';
export * from './hooks';
export * from './email-client';
export * from './types';

export type { TestFile } from './media-helper';
89 changes: 37 additions & 52 deletions packages/calypso-e2e/src/media-helper.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { constants } from 'fs';
import fs from 'fs/promises';
import os from 'os';
import path from 'path';
Expand Down Expand Up @@ -56,72 +57,56 @@ export function getVideoDir(): string {
/**
* Creates a temporary test file by cloning a source file under a new name.
*
* @param {string} sourcePath Full path on disk of the source file.
* @param {{[key: string]: string}} param0 Parameter object.
* @param {string} param0.sourceFileName Basename of the source file to be cloned.
* @param {string} [param0.testFileName] Basename of the test file to be generated.
* @param {string} [param0.postfix] Additional suffix to be used for the file.
* @returns {Promise<TestFile>} Object implementing the TestFile interface.
* @throws {Error} If source file was not found, or source file did not contain an extension.
*/
export async function createTestFile( {
sourceFileName,
testFileName,
}: {
sourceFileName: string;
testFileName?: string;
} ): Promise< TestFile > {
let filename = getTimestamp();
// If the output `testFileName` is defined, use that as part of the final filename.
if ( testFileName ) {
filename += `-${ testFileName }`;
export async function createTestFile(
sourcePath: string,
{
postfix,
}: {
postfix?: string;
} = {}
): Promise< TestFile > {
// Check whether the source file maps to a file.
// Note, if sourcePath is not found use console.error instead of throw:
// https://github.com/facebook/jest/issues/8688
try {
await fs.access( sourcePath );
} catch {
throw new Error( `Source file ${ sourcePath } not found on disk.` );
}

const extension = sourceFileName.split( '.' ).pop();
// Obtain the file extension.
const extension = path.extname( sourcePath );
if ( ! extension ) {
throw new Error( `Extension not found on source file ${ sourceFileName }` );
throw new Error( `Extension not found on source file ${ sourcePath }` );
}

// Generate a filename using current timestamp and a pseudo-randomly generated integer.
let filename = getTimestamp();
// If `postfix` is defined, use that as part of the final filename.
if ( postfix ) {
filename += `-${ postfix }`;
}
const basename = `${ filename }.${ sourceFileName.split( '.' ).pop() }`;
// Create test files in the same directory as the source file.
const dirname = path.join( __dirname, '' );
// Full path on disk of the source file, to be copied and renamed.
const sourceFilePath = path.join( dirname, sourceFileName );

const tempDir = await fs.mkdtemp( path.join( os.tmpdir(), 'e2e-' ) );
const testFilePath = path.join( tempDir, basename );
// Obtain the basename (filename with extension)
const basename = `${ filename }${ extension }`;

const tempDir = await fs.mkdtemp( path.join( os.tmpdir(), 'e2e' ) );
const targetPath = path.join( tempDir, basename );

await fs.copyFile( sourceFilePath, testFilePath );
await fs.copyFile( sourcePath, targetPath, constants.COPYFILE_EXCL );

// Return an object implementing the interface.
return {
fullpath: testFilePath,
dirname: dirname,
fullpath: targetPath,
dirname: tempDir,
basename: basename,
filename: filename,
extension: extension,
};
}

/**
* Returns the path to a generated temporary JPEG image file.
*
* @returns {Promise<TestFile>} Object implementing the TestFile interface.
*/
export async function createTestImage(): Promise< TestFile > {
return await createTestFile( { sourceFileName: 'image0.jpg' } );
}

/**
* Returns the path to a generated temporary MP3 audio file.
*
* @returns {Promise<TestFile>} Object implementing the TestFile interface.
*/
export async function createTestAudio(): Promise< TestFile > {
return await createTestFile( { sourceFileName: 'bees.mp3' } );
}

/**
* Returns the path to an unsupported file.
*
* @returns {Promise<TestFile>} Object implementing the TestFile interface.
*/
export async function createUnsupportedFile(): Promise< TestFile > {
return await createTestFile( { sourceFileName: 'unsupported_extension.mkv' } );
}
2 changes: 0 additions & 2 deletions packages/calypso-e2e/src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,3 @@ export type viewportSize = {
width: number;
height: number;
};

export type { TestFile } from './media-helper';
Binary file removed packages/calypso-e2e/test-files/bees.mp3
Binary file not shown.
Binary file removed packages/calypso-e2e/test-files/image0.jpg
Binary file not shown.
Binary file removed packages/calypso-e2e/test-files/image1.jpg
Binary file not shown.
Binary file removed packages/calypso-e2e/test-files/image2.jpg
Binary file not shown.
Binary file not shown.
12 changes: 12 additions & 0 deletions test/e2e/lib/jest/environment.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const JestEnvironmentNode = require( 'jest-environment-node' );

class JestEnvironmentE2E extends JestEnvironmentNode {
testFailed = false;
hookFailed = false;

async handleTestEvent( event ) {
switch ( event.name ) {
Expand All @@ -16,9 +17,20 @@ class JestEnvironmentE2E extends JestEnvironmentNode {
if ( this.testFailed ) {
event.test.mode = 'skip';
}
// With this flag enabled, all test cases in the describe
// block will be marked as failed.
// This way all other hooks (screenshot/recording) are run,
// and Jest correctly exits after those hooks are run.
if ( this.hookFailed ) {
event.test.mode = 'fail';
}
break;

case 'hook_failure':
this.global.__CURRENT_TEST_FAILED__ = true;
this.hookFailed = true;
break;

case 'test_fn_failure':
this.global.__CURRENT_TEST_FAILED__ = true;
this.testFailed = true;
Expand Down
11 changes: 11 additions & 0 deletions test/e2e/specs/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import path from 'path';

export const TEST_IMAGE_PATH = path.normalize(
path.join( __dirname, '..', 'image-uploads', 'image0.jpg' )
);
export const TEST_AUDIO_PATH = path.normalize(
path.join( __dirname, '..', 'image-uploads', 'bees.mp3' )
);
export const UNSUPPORTED_FILE_PATH = path.normalize(
path.join( __dirname, '..', 'image-uploads', 'unsupported_extension.mkv' )
);
12 changes: 6 additions & 6 deletions test/e2e/specs/specs-playwright/wp-blocks__coblocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
* @group gutenberg
*/

import path from 'path';
import {
setupHooks,
DataHelper,
Expand All @@ -15,11 +14,12 @@ import {
HeroBlock,
ClicktoTweetBlock,
LogosBlock,
TestFile,
} from '@automattic/calypso-e2e';
import { Page } from 'playwright';
import type { TestFile } from '@automattic/calypso-e2e';
import { TEST_IMAGE_PATH } from '../constants';

describe( DataHelper.createSuiteTitle( 'Blocks: CoBlocks' ), () => {
describe( DataHelper.createSuiteTitle( 'Blocks: CoBlocks' ), function () {
let gutenbergEditorPage: GutenbergEditorPage;
let pricingTableBlock: PricingTableBlock;
let page: Page;
Expand All @@ -31,12 +31,12 @@ describe( DataHelper.createSuiteTitle( 'Blocks: CoBlocks' ), () => {
const clicktoTweetBlockTweet =
'The foolish man seeks happiness in the distance. The wise grows it under his feet. — James Oppenheim';

setupHooks( ( args ) => {
setupHooks( ( args: { page: Page } ) => {
page = args.page;
} );

beforeAll( async () => {
logoImage = await MediaHelper.createTestImage();
logoImage = await MediaHelper.createTestFile( TEST_IMAGE_PATH );
} );

it( 'Log in', async function () {
Expand Down Expand Up @@ -105,6 +105,6 @@ describe( DataHelper.createSuiteTitle( 'Blocks: CoBlocks' ), () => {
);

it( `Confirm Logos block is visible in published post`, async () => {
await LogosBlock.validatePublishedContent( page, logoImage.basename );
await LogosBlock.validatePublishedContent( page, [ logoImage.filename ] );
} );
} );
32 changes: 15 additions & 17 deletions test/e2e/specs/specs-playwright/wp-blocks__media-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
* @group gutenberg
*/

import path from 'path';
import {
setupHooks,
DataHelper,
Expand All @@ -17,8 +16,9 @@ import {
TestFile,
} from '@automattic/calypso-e2e';
import { Page } from 'playwright';
import { TEST_IMAGE_PATH, TEST_AUDIO_PATH } from '../constants';

describe( DataHelper.createSuiteTitle( 'Blocks: Media (Upload)' ), () => {
describe( DataHelper.createSuiteTitle( 'Blocks: Media (Upload)' ), function () {
let gutenbergEditorPage: GutenbergEditorPage;
let page: Page;
let testFiles: { image: TestFile; image_reserved_name: TestFile; audio: TestFile };
Expand All @@ -29,12 +29,11 @@ describe( DataHelper.createSuiteTitle( 'Blocks: Media (Upload)' ), () => {

beforeAll( async () => {
testFiles = {
image: await MediaHelper.createTestImage(),
image_reserved_name: await MediaHelper.createTestFile( {
sourceFileName: 'image0.jpg',
testFileName: 'filewith#?#?reservedurlchars',
image: await MediaHelper.createTestFile( TEST_IMAGE_PATH ),
image_reserved_name: await MediaHelper.createTestFile( TEST_IMAGE_PATH, {
postfix: 'filewith#?#?reservedurlchars',
} ),
audio: await MediaHelper.createTestAudio(),
audio: await MediaHelper.createTestFile( TEST_AUDIO_PATH ),
};
} );

Expand Down Expand Up @@ -84,22 +83,21 @@ describe( DataHelper.createSuiteTitle( 'Blocks: Media (Upload)' ), () => {
await gutenbergEditorPage.publish( { visit: true, saveDraft: true } );
} );

it( `Confirm Image block is visible in published post`, async () => {
await ImageBlock.validatePublishedContent( page, testFiles.image.filename );
it( `Confirm Image block is visible in published post`, async function () {
await ImageBlock.validatePublishedContent( page, [ testFiles.image.filename ] );
} );

it( `Confirm Image block is visible in published post (reserved name)`, async () => {
await ImageBlock.validatePublishedContent(
page,
testFiles.image_reserved_name.filename.replace( /[^a-zA-Z ]/g, '' )
);
it( `Confirm Image block is visible in published post (reserved name)`, async function () {
await ImageBlock.validatePublishedContent( page, [
testFiles.image_reserved_name.filename.replace( /[^a-zA-Z ]/g, '' ),
] );
} );

it( `Confirm Audio block is visible in published post`, async () => {
it( `Confirm Audio block is visible in published post`, async function () {
await AudioBlock.validatePublishedContent( page );
} );

it( `Confirm File block is visible in published post`, async () => {
await FileBlock.validatePublishedContent( page, testFiles.audio.filename );
it( `Confirm File block is visible in published post`, async function () {
await FileBlock.validatePublishedContent( page, [ testFiles.audio.filename ] );
} );
} );
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,29 @@ import {
MediaPage,
SidebarComponent,
setupHooks,
TestFile,
} from '@automattic/calypso-e2e';
import { Page } from 'playwright';
import { TEST_IMAGE_PATH } from '../constants';

describe( DataHelper.createSuiteTitle( 'Media: Edit Media' ), function () {
let testImage;
let page;
let testImage: TestFile;
let page: Page;

setupHooks( ( args ) => {
page = args.page;
} );

beforeAll( async () => {
testImage = await MediaHelper.createTestImage();
testImage = await MediaHelper.createTestFile( TEST_IMAGE_PATH );
} );

describe.each`
siteType | user
${ 'Simple' } | ${ 'defaultUser' }
${ 'Atomic' } | ${ 'wooCommerceUser' }
`( 'Edit Image ($siteType)', function ( { user } ) {
let mediaPage;
let mediaPage: MediaPage;

it( 'Log In', async function () {
const loginFlow = new LoginFlow( page, user );
Expand Down
13 changes: 7 additions & 6 deletions test/e2e/specs/specs-playwright/wp-media__upload-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
TestFile,
} from '@automattic/calypso-e2e';
import { Page } from 'playwright';
import { TEST_IMAGE_PATH, TEST_AUDIO_PATH, UNSUPPORTED_FILE_PATH } from '../constants';

describe( DataHelper.createSuiteTitle( 'Media: Upload' ), () => {
let testFiles: { image: TestFile; audio: TestFile; unsupported: TestFile };
Expand All @@ -24,9 +25,9 @@ describe( DataHelper.createSuiteTitle( 'Media: Upload' ), () => {

beforeAll( async () => {
testFiles = {
image: await MediaHelper.createTestImage(),
audio: await MediaHelper.createTestAudio(),
unsupported: await MediaHelper.createUnsupportedFile(),
image: await MediaHelper.createTestFile( TEST_IMAGE_PATH ),
audio: await MediaHelper.createTestFile( TEST_AUDIO_PATH ),
unsupported: await MediaHelper.createTestFile( UNSUPPORTED_FILE_PATH ),
};
} );

Expand All @@ -53,18 +54,18 @@ describe( DataHelper.createSuiteTitle( 'Media: Upload' ), () => {
} );

it( 'Upload image and confirm addition to gallery', async () => {
const uploadedItem = await mediaPage.upload( testFiles.image );
const uploadedItem = await mediaPage.upload( testFiles.image.fullpath );
assert.strictEqual( await uploadedItem.isVisible(), true );
} );

it( 'Upload audio and confirm addition to gallery', async () => {
const uploadedItem = await mediaPage.upload( testFiles.audio );
const uploadedItem = await mediaPage.upload( testFiles.audio.fullpath );
assert.strictEqual( await uploadedItem.isVisible(), true );
} );

it( 'Upload an unsupported file type and see the rejection notice', async function () {
try {
await mediaPage.upload( testFiles.unsupported );
await mediaPage.upload( testFiles.unsupported.fullpath );
} catch ( error ) {
assert.match( error.message, /could not be uploaded/i );
}
Expand Down
4 changes: 2 additions & 2 deletions test/e2e/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"extends": "@automattic/calypso-build/typescript/ts-package.json",
"compilerOptions": {
"allowJs": true,
"noEmit": true, // just type checking, no output. The output is handled by babel.
"types": [ "jest", "node" ] // no mocha - we are only using TypeScript for the new Playwright scripts
},
// TypeScript is scoped only for the new Playwright scripts
"include": [ "specs/specs-playwright", "lib/gutenberg/tracking" ]
"include": [ "specs/specs-playwright", "specs/constants.js", "lib/gutenberg/tracking" ]
}

0 comments on commit eedb093

Please sign in to comment.