-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Make i18n functions filter their return values (#27966)
* Make i18n functions filter their return values * @wordpress/hooks local dependency * Support for domain-specific filters as per PHP * Move responsibility for creating applyFilters to default-i18n * Add tests * Flag dependency in tsconfig.json * package-lock changes * Coding standards fix * Introduce i18n-filters test * Include i18n-filters test in CI task * More consistent (not perfect) hook attachment * Test fix * Nit: type names start with a capital letter * Add default i18n tests * Use type annotations rather than explicit conversion Co-authored-by: Lee Willis <[email protected]>
- Loading branch information
1 parent
1a54497
commit 736a005
Showing
11 changed files
with
568 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
291 changes: 291 additions & 0 deletions
291
packages/e2e-tests/specs/performance/i18n-filters.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,291 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { basename, join } from 'path'; | ||
import { existsSync, readFileSync, unlinkSync, writeFileSync } from 'fs'; | ||
|
||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { | ||
createNewPost, | ||
saveDraft, | ||
insertBlock, | ||
openGlobalBlockInserter, | ||
closeGlobalBlockInserter, | ||
} from '@wordpress/e2e-test-utils'; | ||
|
||
function readFile( filePath ) { | ||
return existsSync( filePath ) | ||
? readFileSync( filePath, 'utf8' ).trim() | ||
: ''; | ||
} | ||
|
||
function deleteFile( filePath ) { | ||
if ( existsSync( filePath ) ) { | ||
unlinkSync( filePath ); | ||
} | ||
} | ||
|
||
function isKeyEvent( item ) { | ||
return ( | ||
item.cat === 'devtools.timeline' && | ||
item.name === 'EventDispatch' && | ||
item.dur && | ||
item.args && | ||
item.args.data | ||
); | ||
} | ||
|
||
function isKeyDownEvent( item ) { | ||
return isKeyEvent( item ) && item.args.data.type === 'keydown'; | ||
} | ||
|
||
function isKeyPressEvent( item ) { | ||
return isKeyEvent( item ) && item.args.data.type === 'keypress'; | ||
} | ||
|
||
function isKeyUpEvent( item ) { | ||
return isKeyEvent( item ) && item.args.data.type === 'keyup'; | ||
} | ||
|
||
function isFocusEvent( item ) { | ||
return isKeyEvent( item ) && item.args.data.type === 'focus'; | ||
} | ||
|
||
function isClickEvent( item ) { | ||
return isKeyEvent( item ) && item.args.data.type === 'click'; | ||
} | ||
|
||
function isMouseOverEvent( item ) { | ||
return isKeyEvent( item ) && item.args.data.type === 'mouseover'; | ||
} | ||
|
||
function isMouseOutEvent( item ) { | ||
return isKeyEvent( item ) && item.args.data.type === 'mouseout'; | ||
} | ||
|
||
function getEventDurationsForType( trace, filterFunction ) { | ||
return trace.traceEvents | ||
.filter( filterFunction ) | ||
.map( ( item ) => item.dur / 1000 ); | ||
} | ||
|
||
function getTypingEventDurations( trace ) { | ||
return [ | ||
getEventDurationsForType( trace, isKeyDownEvent ), | ||
getEventDurationsForType( trace, isKeyPressEvent ), | ||
getEventDurationsForType( trace, isKeyUpEvent ), | ||
]; | ||
} | ||
|
||
function getSelectionEventDurations( trace ) { | ||
return [ getEventDurationsForType( trace, isFocusEvent ) ]; | ||
} | ||
|
||
function getClickEventDurations( trace ) { | ||
return [ getEventDurationsForType( trace, isClickEvent ) ]; | ||
} | ||
|
||
function getHoverEventDurations( trace ) { | ||
return [ | ||
getEventDurationsForType( trace, isMouseOverEvent ), | ||
getEventDurationsForType( trace, isMouseOutEvent ), | ||
]; | ||
} | ||
|
||
page.on( 'load', function () { | ||
page.evaluate( () => { | ||
const filters = [ | ||
'i18n.gettext', | ||
'i18n.gettext_default', | ||
'i18n.ngettext', | ||
'i18n.ngettext_default', | ||
'i18n.gettext_with_context', | ||
'i18n.gettext_with_context_default', | ||
'i18n.ngettext_with_context', | ||
'i18n.ngettext_with_context_default', | ||
]; | ||
filters.forEach( ( filter ) => { | ||
wp.hooks.addFilter( | ||
filter, | ||
'e2e-tests', | ||
( ...args ) => { | ||
return args[ 0 ]; | ||
}, | ||
90 | ||
); | ||
} ); | ||
} ); | ||
} ); | ||
|
||
jest.setTimeout( 1000000 ); | ||
|
||
describe( 'Post Editor Performance (with i18n filters)', () => { | ||
it( 'Loading, typing and selecting blocks', async () => { | ||
const results = { | ||
load: [], | ||
type: [], | ||
focus: [], | ||
inserterOpen: [], | ||
inserterHover: [], | ||
}; | ||
|
||
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/block-editor' ).resetBlocks( blocks ); | ||
}, html ); | ||
await saveDraft(); | ||
|
||
let i = 1; | ||
|
||
// Measuring loading time | ||
while ( i-- ) { | ||
const startTime = new Date(); | ||
await page.reload(); | ||
await page.waitForSelector( '.wp-block' ); | ||
results.load.push( new Date() - startTime ); | ||
} | ||
|
||
// Measure time to open inserter | ||
await page.waitForSelector( '.edit-post-layout' ); | ||
const traceFile = __dirname + '/trace.json'; | ||
let traceResults; | ||
for ( let j = 0; j < 10; j++ ) { | ||
await page.tracing.start( { | ||
path: traceFile, | ||
screenshots: false, | ||
categories: [ 'devtools.timeline' ], | ||
} ); | ||
await openGlobalBlockInserter(); | ||
await page.tracing.stop(); | ||
|
||
traceResults = JSON.parse( readFile( traceFile ) ); | ||
const [ mouseClickEvents ] = getClickEventDurations( traceResults ); | ||
for ( let k = 0; k < mouseClickEvents.length; k++ ) { | ||
results.inserterOpen.push( mouseClickEvents[ k ] ); | ||
} | ||
await closeGlobalBlockInserter(); | ||
} | ||
|
||
// Measure inserter hover performance | ||
const paragraphBlockItem = | ||
'.block-editor-inserter__menu .editor-block-list-item-paragraph'; | ||
const headingBlockItem = | ||
'.block-editor-inserter__menu .editor-block-list-item-heading'; | ||
await openGlobalBlockInserter(); | ||
await page.waitForSelector( paragraphBlockItem ); | ||
await page.hover( paragraphBlockItem ); | ||
await page.hover( headingBlockItem ); | ||
for ( let j = 0; j < 20; j++ ) { | ||
await page.tracing.start( { | ||
path: traceFile, | ||
screenshots: false, | ||
categories: [ 'devtools.timeline' ], | ||
} ); | ||
await page.hover( paragraphBlockItem ); | ||
await page.hover( headingBlockItem ); | ||
await page.tracing.stop(); | ||
|
||
traceResults = JSON.parse( readFile( traceFile ) ); | ||
const [ mouseOverEvents, mouseOutEvents ] = getHoverEventDurations( | ||
traceResults | ||
); | ||
for ( let k = 0; k < mouseOverEvents.length; k++ ) { | ||
results.inserterHover.push( | ||
mouseOverEvents[ k ] + mouseOutEvents[ k ] | ||
); | ||
} | ||
} | ||
await closeGlobalBlockInserter(); | ||
|
||
// Measuring typing performance | ||
await insertBlock( 'Paragraph' ); | ||
i = 200; | ||
await page.tracing.start( { | ||
path: traceFile, | ||
screenshots: false, | ||
categories: [ 'devtools.timeline' ], | ||
} ); | ||
while ( i-- ) { | ||
await page.keyboard.type( 'x' ); | ||
} | ||
|
||
await page.tracing.stop(); | ||
traceResults = JSON.parse( readFile( traceFile ) ); | ||
const [ | ||
keyDownEvents, | ||
keyPressEvents, | ||
keyUpEvents, | ||
] = getTypingEventDurations( traceResults ); | ||
|
||
if ( | ||
keyDownEvents.length === keyPressEvents.length && | ||
keyPressEvents.length === keyUpEvents.length | ||
) { | ||
for ( let j = 0; j < keyDownEvents.length; j++ ) { | ||
results.type.push( | ||
keyDownEvents[ j ] + keyPressEvents[ j ] + keyUpEvents[ j ] | ||
); | ||
} | ||
} | ||
|
||
// Save the draft so we don't get browser dialogs about leaving unsaved page. | ||
await saveDraft(); | ||
|
||
// Measuring block selection performance | ||
await createNewPost(); | ||
await page.evaluate( () => { | ||
const { createBlock } = window.wp.blocks; | ||
const { dispatch } = window.wp.data; | ||
const blocks = window.lodash | ||
.times( 1000 ) | ||
.map( () => createBlock( 'core/paragraph' ) ); | ||
dispatch( 'core/block-editor' ).resetBlocks( blocks ); | ||
} ); | ||
|
||
const paragraphs = await page.$$( '.wp-block' ); | ||
|
||
await page.tracing.start( { | ||
path: traceFile, | ||
screenshots: false, | ||
categories: [ 'devtools.timeline' ], | ||
} ); | ||
for ( let j = 0; j < 10; j++ ) { | ||
await paragraphs[ j ].click(); | ||
} | ||
|
||
await page.tracing.stop(); | ||
|
||
traceResults = JSON.parse( readFile( traceFile ) ); | ||
const [ focusEvents ] = getSelectionEventDurations( traceResults ); | ||
results.focus = focusEvents; | ||
|
||
const resultsFilename = basename( __filename, '.js' ) + '.results.json'; | ||
|
||
writeFileSync( | ||
join( __dirname, resultsFilename ), | ||
JSON.stringify( results, null, 2 ) | ||
); | ||
|
||
deleteFile( traceFile ); | ||
|
||
expect( true ).toBe( true ); | ||
} ); | ||
} ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.