Skip to content

Commit

Permalink
Tests: Introduce automated manual test sample for performance testing.
Browse files Browse the repository at this point in the history
  • Loading branch information
scofalik committed Oct 2, 2024
1 parent 915c3a7 commit 8fbb261
Show file tree
Hide file tree
Showing 12 changed files with 614 additions and 0 deletions.
220 changes: 220 additions & 0 deletions tests/manual/performance/2024/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
import Alignment from '@ckeditor/ckeditor5-alignment/src/alignment.js';
import ArticlePluginSet from '@ckeditor/ckeditor5-core/tests/_utils/articlepluginset.js';
import AutoImage from '@ckeditor/ckeditor5-image/src/autoimage.js';
import AutoLink from '@ckeditor/ckeditor5-link/src/autolink.js';
import Code from '@ckeditor/ckeditor5-basic-styles/src/code.js';
import CodeBlock from '@ckeditor/ckeditor5-code-block/src/codeblock.js';
import EasyImage from '@ckeditor/ckeditor5-easy-image/src/easyimage.js';
import FindAndReplace from '@ckeditor/ckeditor5-find-and-replace/src/findandreplace.js';
import FontBackgroundColor from '@ckeditor/ckeditor5-font/src/fontbackgroundcolor.js';
import FontColor from '@ckeditor/ckeditor5-font/src/fontcolor.js';
import FontFamily from '@ckeditor/ckeditor5-font/src/fontfamily.js';
import FontSize from '@ckeditor/ckeditor5-font/src/fontsize.js';
import Highlight from '@ckeditor/ckeditor5-highlight/src/highlight.js';
import HorizontalLine from '@ckeditor/ckeditor5-horizontal-line/src/horizontalline.js';
import HtmlEmbed from '@ckeditor/ckeditor5-html-embed/src/htmlembed.js';
import HtmlComment from '@ckeditor/ckeditor5-html-support/src/htmlcomment.js';
import ImageResize from '@ckeditor/ckeditor5-image/src/imageresize.js';
import ImageInsert from '@ckeditor/ckeditor5-image/src/imageinsert.js';
import IndentBlock from '@ckeditor/ckeditor5-indent/src/indentblock.js';
import LinkImage from '@ckeditor/ckeditor5-link/src/linkimage.js';
import ListProperties from '@ckeditor/ckeditor5-list/src/listproperties.js';
import Mention from '@ckeditor/ckeditor5-mention/src/mention.js';
import PageBreak from '@ckeditor/ckeditor5-page-break/src/pagebreak.js';
import PasteFromOffice from '@ckeditor/ckeditor5-paste-from-office/src/pastefromoffice.js';
import RemoveFormat from '@ckeditor/ckeditor5-remove-format/src/removeformat.js';
import ShowBlocks from '@ckeditor/ckeditor5-show-blocks/src/showblocks.js';
import SourceEditing from '@ckeditor/ckeditor5-source-editing/src/sourceediting.js';
import SpecialCharacters from '@ckeditor/ckeditor5-special-characters/src/specialcharacters.js';
import SpecialCharactersEssentials from '@ckeditor/ckeditor5-special-characters/src/specialcharactersessentials.js';
import Strikethrough from '@ckeditor/ckeditor5-basic-styles/src/strikethrough.js';
import Subscript from '@ckeditor/ckeditor5-basic-styles/src/subscript.js';
import Superscript from '@ckeditor/ckeditor5-basic-styles/src/superscript.js';
import TableCellProperties from '@ckeditor/ckeditor5-table/src/tablecellproperties.js';
import TableProperties from '@ckeditor/ckeditor5-table/src/tableproperties.js';
import TableCaption from '@ckeditor/ckeditor5-table/src/tablecaption.js';
import TableColumnResize from '@ckeditor/ckeditor5-table/src/tablecolumnresize.js';
import TextTransformation from '@ckeditor/ckeditor5-typing/src/texttransformation.js';
import TextPartLanguage from '@ckeditor/ckeditor5-language/src/textpartlanguage.js';
import TodoList from '@ckeditor/ckeditor5-list/src/todolist.js';
import Underline from '@ckeditor/ckeditor5-basic-styles/src/underline.js';
import WordCount from '@ckeditor/ckeditor5-word-count/src/wordcount.js';
import CloudServices from '@ckeditor/ckeditor5-cloud-services/src/cloudservices.js';
import Style from '@ckeditor/ckeditor5-style/src/style.js';
import GeneralHtmlSupport from '@ckeditor/ckeditor5-html-support/src/generalhtmlsupport.js';

import { CS_CONFIG } from '@ckeditor/ckeditor5-cloud-services/tests/_utils/cloud-services-config.js';

export default {
plugins: [
ArticlePluginSet, Underline, Strikethrough, Superscript, Subscript, Code, RemoveFormat,
FindAndReplace, FontColor, FontBackgroundColor, FontFamily, FontSize, Highlight,
CodeBlock, TodoList, ListProperties, TableProperties, TableCellProperties, TableCaption, TableColumnResize,
EasyImage, ImageResize, ImageInsert, LinkImage, AutoImage, HtmlEmbed, HtmlComment,
AutoLink, Mention, TextTransformation,
Alignment, IndentBlock,
PasteFromOffice, PageBreak, HorizontalLine, ShowBlocks,
SpecialCharacters, SpecialCharactersEssentials, WordCount,
CloudServices, TextPartLanguage, SourceEditing, Style, GeneralHtmlSupport
],
toolbar: [
'heading', 'style',
'|',
'removeFormat', 'bold', 'italic', 'strikethrough', 'underline', 'code', 'subscript', 'superscript', 'link',
'|',
'highlight', 'fontSize', 'fontFamily', 'fontColor', 'fontBackgroundColor',
'|',
'bulletedList', 'numberedList', 'todoList',
'|',
'blockQuote', 'insertImage', 'insertTable', 'mediaEmbed', 'codeBlock',
'|',
'htmlEmbed',
'|',
'alignment', 'outdent', 'indent',
'|',
'pageBreak', 'horizontalLine', 'specialCharacters',
'|',
'textPartLanguage',
'|',
'sourceEditing', 'showBlocks',
'|',
'undo', 'redo', 'findAndReplace'
],
cloudServices: CS_CONFIG,
table: {
contentToolbar: [
'tableColumn', 'tableRow', 'mergeTableCells', 'tableProperties', 'tableCellProperties', 'toggleTableCaption'
]
},
image: {
styles: [
'alignCenter',
'alignLeft',
'alignRight'
],
resizeOptions: [
{
name: 'resizeImage:original',
label: 'Original size',
value: null
},
{
name: 'resizeImage:50',
label: '50%',
value: '50'
},
{
name: 'resizeImage:75',
label: '75%',
value: '75'
}
],
toolbar: [
'imageTextAlternative', 'toggleImageCaption', '|',
'imageStyle:inline', 'imageStyle:breakText', 'imageStyle:wrapText', '|',
'resizeImage'
]
},
placeholder: 'Type the content here!',
mention: {
feeds: [
{
marker: '@',
feed: [
'@apple', '@bears', '@brownie', '@cake', '@cake', '@candy', '@canes', '@chocolate', '@cookie', '@cotton', '@cream',
'@cupcake', '@danish', '@donut', '@dragée', '@fruitcake', '@gingerbread', '@gummi', '@ice', '@jelly-o',
'@liquorice', '@macaroon', '@marzipan', '@oat', '@pie', '@plum', '@pudding', '@sesame', '@snaps', '@soufflé',
'@sugar', '@sweet', '@topping', '@wafer'
],
minimumCharacters: 1
}
]
},
menuBar: {
isVisible: true
},
link: {
decorators: {
isExternal: {
mode: 'manual',
label: 'Open in a new tab',
attributes: {
target: '_blank',
rel: 'noopener noreferrer'
}
},
isDownloadable: {
mode: 'manual',
label: 'Downloadable',
attributes: {
download: 'download'
}
},
isGallery: {
mode: 'manual',
label: 'Gallery link',
classes: 'gallery'
}
}
},
htmlEmbed: {
showPreviews: true,
sanitizeHtml: html => ( { html, hasChange: false } )
},
list: {
properties: {
styles: true,
startIndex: true,
reversed: true
}
},
style: {
definitions: [
{
name: 'Article category',
element: 'h3',
classes: [ 'category' ]
},
{
name: 'Title',
element: 'h2',
classes: [ 'document-title' ]
},
{
name: 'Subtitle',
element: 'h3',
classes: [ 'document-subtitle' ]
},
{
name: 'Info box',
element: 'p',
classes: [ 'info-box' ]
},
{
name: 'Side quote',
element: 'blockquote',
classes: [ 'side-quote' ]
},
{
name: 'Marker',
element: 'span',
classes: [ 'marker' ]
},
{
name: 'Spoiler',
element: 'span',
classes: [ 'spoiler' ]
},
{
name: 'Code (dark)',
element: 'pre',
classes: [ 'fancy-code', 'fancy-code-dark' ]
},
{
name: 'Code (bright)',
element: 'pre',
classes: [ 'fancy-code', 'fancy-code-bright' ]
}
]
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Creates 40 paragraphs, each with a 1000 of text nodes, each text node is wrapped in an HTML tag that will be converted to text attribute.
// This is a counterpart data set to `formatting-short-paragraphs` where both tests have same total number of text nodes, but
// we observed that longer paragraphs have significant negative impact on editor performance.
// Note, that long, non-formatted paragraphs are not problematic as these texts are treated as one text node.
// We had instances where long non-formatted paragraphs were problematic, but these had always some formatting and `<br>`s which also
// spread text into multiple text nodes.
export default function makeData() {
let initialData = '';

for ( let i = 0; i < 40; i++ ) {
initialData += '<p>';

for ( let j = 0; j < 1000; j++ ) {
if ( j % 3 === 0 ) {
initialData += '<strong>Lorem ipsum</strong>';
} else if ( j % 3 === 1 ) {
initialData += '<em> dolor sit </em>';
} else {
initialData += '<s>amet. </s>';
}
}

initialData += '</p>';
}

return initialData;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Creates 800 paragraphs, each with a 50 of text nodes, each text node is wrapped in an HTML tag that will be converted to text attribute.
// This test how text formatting affects the editor loading speed.
export default function makeData() {
let initialData = '';

for ( let i = 0; i < 800; i++ ) {
initialData += '<p>';

for ( let j = 0; j < 50; j++ ) {
if ( j % 3 === 0 ) {
initialData += '<strong>Lorem ipsum</strong>';
} else if ( j % 3 === 1 ) {
initialData += '<em> dolor sit </em>';
} else {
initialData += '<s>amet. </s>';
}
}

initialData += '</p>';
}

return initialData;
}
11 changes: 11 additions & 0 deletions tests/manual/performance/2024/data/generated/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import paragraphs from './paragraphs.js';
import lists from './lists.js';
import tableHuge from './table-huge.js';
import tablesMany from './tables-many-smaller.js';
import formattingLongP from './formatting-long-paragraphs.js';
import formattingShortP from './formatting-short-paragraphs.js';
import inlineStyles from './inline-styles.js';

export default {
paragraphs, lists, tableHuge, tablesMany, formattingLongP, formattingShortP, inlineStyles
};
20 changes: 20 additions & 0 deletions tests/manual/performance/2024/data/generated/inline-styles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Creates 30 paragraphs, each with a 1000 of text nodes, half of the text nodes is wrapped in a span with inline styles.
export default function makeData() {
let initialData = '';

for ( let i = 0; i < 30; i++ ) {
initialData += '<p>';

for ( let j = 0; j < 1000; j++ ) {
if ( j % 2 === 0 ) {
initialData += '<span style="font-weight:bold;font-style:italic;text-decoration:underline;color:#808080;font-family: Arial;background:#EEEEEE;">Lorem ipsum dolor</span>';
} else {
initialData += ' sit amet. ';
}
}

initialData += '</p>';
}

return initialData;
}
36 changes: 36 additions & 0 deletions tests/manual/performance/2024/data/generated/lists.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Creates multiple, nested lists, for a total of 3000 list items. Text in lists is simple, short, non-formatted text.
// This tests editor performance when huge lists are in the content.
// Below data creates 100 pages when copy-pasted to Google Docs (default page settings).
export default function makeData() {
let initialData = '';

// Create 25 top-level lists, each with ~90 nested items total, on multiple levels.
for ( let i = 0; i < 25; i++ ) {
const tagName = i % 2 ? 'ul' : 'ol';

initialData += makeList( 40, tagName, 3 );
}

return initialData;
}

function makeList( itemsCount, tagName, levels ) {
let initialData = `<${ tagName }>`;

for ( let i = 0; i < itemsCount / 2; i++ ) {
initialData += '<li>Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet.</li>';
}

if ( levels > 1 ) {
initialData += '<li>Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet.';
initialData += makeList( itemsCount, levels % 2 ? 'ul' : 'ol', levels - 1 );
}

for ( let i = 0; i < itemsCount / 2; i++ ) {
initialData += '<li>Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet.</li>';
}

initialData += `</${ tagName }>`;

return initialData;
}
16 changes: 16 additions & 0 deletions tests/manual/performance/2024/data/generated/paragraphs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// This is the most basic performance test, where we load many paragraphs (5000) and fill them with reasonable text volume, no formatting.
// Below data creates 400 pages when copy-pasted to Google Docs (default page settings).
export default function makeData() {
let initialData = '';

for ( let i = 0; i < 5000; i++ ) {
initialData +=
'<p>' +
'Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. ' +
'Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. ' +
'Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. ' +
'</p>'
}

return initialData;
}
21 changes: 21 additions & 0 deletions tests/manual/performance/2024/data/generated/table-huge.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Creates one table with 2000 rows and 10 columns, total 20000 cells.
// This tests editor performance when huge tables are in content.
export default function makeData() {
let initialData = '';

initialData += '<table>'

for ( let i = 0; i < 2000; i++ ) {
initialData += '<tr>';

for ( let j = 0; j < 10; j++ ) {
initialData += '<td>Lorem foo bar</td>';
}

initialData += '</tr>';
}

initialData += '</table>';

return initialData;
}
Loading

0 comments on commit 8fbb261

Please sign in to comment.