Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Performance: add e2e tests for load and typing time #14506

Merged
merged 7 commits into from
May 28, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@
"pretest-e2e": "cross-env SCRIPT_DEBUG=false ./bin/reset-local-e2e-tests.sh",
"test-e2e": "wp-scripts test-e2e --config packages/e2e-tests/jest.config.js",
"test-e2e:watch": "npm run test-e2e -- --watch",
"test-performance": "wp-scripts test-e2e --config packages/e2e-tests/jest.performance.config.js",
"test-php": "npm run lint-php && npm run test-unit-php",
"test-unit": "wp-scripts test-unit-js --config test/unit/jest.config.js",
"test-unit:update": "npm run test-unit -- --updateSnapshot",
Expand Down
3,989 changes: 3,989 additions & 0 deletions packages/e2e-tests/assets/large-post.html

Large diffs are not rendered by default.

29 changes: 29 additions & 0 deletions packages/e2e-tests/config/performance-reporter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const { readFileSync, existsSync } = require( 'fs' );

function average( array ) {
return array.reduce( ( a, b ) => a + b ) / array.length;
}

class PerformanceReporter {
onRunComplete() {
const path = __dirname + '/../specs/results.json';

if ( ! existsSync( path ) ) {
return;
}

const results = readFileSync( path, 'utf8' );
const { load, domcontentloaded, type } = JSON.parse( results );

// eslint-disable-next-line no-console
console.log( `
Average time to load: ${ average( load ) }ms
Average time to DOM content load: ${ average( domcontentloaded ) }ms
Average time to type character: ${ average( type ) }ms
Slowest time to type character: ${ Math.max( ...type ) }ms
Fastest time to type character: ${ Math.min( ...type ) }ms
` );
}
}

module.exports = PerformanceReporter;
3 changes: 3 additions & 0 deletions packages/e2e-tests/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,7 @@ module.exports = {
'@wordpress/jest-puppeteer-axe',
'expect-puppeteer',
],
testPathIgnorePatterns: [
'e2e-tests/specs/performance.test.js',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we put it into its own folder to avoid this ignore rule?

e2e-tests/benchmark/index.js - should do the trick

],
};
23 changes: 23 additions & 0 deletions packages/e2e-tests/jest.performance.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module.exports = {
...require( '@wordpress/scripts/config/jest-e2e.config' ),
testMatch: [
'**/performance.test.js',
],
setupFiles: [
'<rootDir>/config/gutenberg-phase.js',
],
setupFilesAfterEnv: [
'<rootDir>/config/setup-test-framework.js',
'@wordpress/jest-console',
'@wordpress/jest-puppeteer-axe',
'expect-puppeteer',
],
transformIgnorePatterns: [
'node_modules',
'scripts/config/puppeteer.config.js',
],
reporters: [
'default',
'<rootDir>/config/performance-reporter.js',
],
};
1 change: 1 addition & 0 deletions packages/e2e-tests/specs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.json
72 changes: 72 additions & 0 deletions packages/e2e-tests/specs/performance.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/**
* External dependencies
*/
import { join } from 'path';
import { existsSync, readFileSync, writeFileSync } from 'fs';

/**
* WordPress dependencies
*/
import {
createNewPost,
saveDraft,
insertBlock,
} from '@wordpress/e2e-test-utils';

function readFile( filePath ) {
return existsSync( filePath ) ? readFileSync( filePath, 'utf8' ).trim() : '';
}

describe( 'Performance', () => {
it( '1000 paragraphs', async () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want it to be executed every time we run e2e tests?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, let's exclude.

const html = readFile( join( __dirname, '../assets/large-post.html' ) );

await createNewPost();
await page.evaluate( ( _html ) => {
const { parse } = window.wp.blocks;
const { dispatch } = window.wp.data;
const blocks = parse( _html );

blocks.forEach( ( block ) => {
if ( block.name === 'core/image' ) {
delete block.attributes.id;
delete block.attributes.url;
}
} );

dispatch( 'core/editor' ).resetBlocks( blocks );
}, html );
await saveDraft();

const results = {
load: [],
domcontentloaded: [],
type: [],
};

let i = 1;
let startTime;

await page.on( 'load', () => results.load.push( new Date() - startTime ) );
await page.on( 'domcontentloaded', () => results.domcontentloaded.push( new Date() - startTime ) );

while ( i-- ) {
startTime = new Date();
await page.reload( { waitUntil: [ 'domcontentloaded', 'load' ] } );
}

await insertBlock( 'Paragraph' );

i = 200;

while ( i-- ) {
startTime = new Date();
await page.keyboard.type( 'x' );
results.type.push( new Date() - startTime );
}

writeFileSync( __dirname + '/results.json', JSON.stringify( results, null, 2 ) );

expect( true ).toBe( true );
} );
} );