Skip to content

Commit 9c2e80c

Browse files
authored
Merge stable into master
2 parents f0422ec + 55a8ee9 commit 9c2e80c

File tree

3 files changed

+197
-1
lines changed

3 files changed

+197
-1
lines changed

docs/getting-started/integrations/angular.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,13 +696,62 @@ There is a known issue related to the localization in Angular 17. Read more in t
696696

697697
## Known issues
698698

699+
### Module resolution
700+
699701
The `moduleResolution` option of the TypeScript configuration determines the algorithm for finding and resolving modules from `node_modules`. In Angular 17, the option is set to `node` by default. This option prevents type declaration for editor translations from being correctly loaded. To fix it, you have several options:
700702

701703
* You can set the `moduleResolution` option to `bundler`. It is the recommended setting in TypeScript 5.0+ for applications that use a bundler. And it is a recommended way of fixing this problem. You can check other solutions below for lower TypeScript versions.
702704
* You can tell the TypeScript compiler to suppress the problem using the `// @ts-expect-error` comment above the imported translations.
703705
* You can update Angular to version 18, where the `moduleResolution` option is set to `bundler` by default.
704706
* You can import translations directly from our CDN, like: `import ‘https://cdn.ckeditor.com/ckeditor5/{@var ckeditor5-version}/translations/es.umd.js’;`. This way, the editor will load the translations automatically, so you do not need to pass them manually into the config.
705707

708+
### Jest testing
709+
710+
You can use Jest as a test runner in Angular apps. Unfortunately, Jest does not use a real browser. Instead, it runs tests in Node.js that uses JSDOM. JSDOM is not a complete DOM implementation, and while it is sufficient for standard apps, it cannot polyfill all the DOM APIs that CKEditor 5 requires.
711+
712+
For testing CKEditor 5, it is recommended to use testing frameworks that utilize a real browser and provide a complete DOM implementation. Some popular options include:
713+
714+
* [Vitest](https://vitest.dev/)
715+
* [Playwright](https://playwright.dev/)
716+
* [Cypress](https://www.cypress.io/)
717+
718+
These frameworks offer better support for testing CKEditor 5 and provide a more accurate representation of how the editor behaves in a real browser environment.
719+
720+
If this is not possible and you still want to use Jest, you can mock some of the required APIs. Below is an example of how to mock some of the APIs used by CKEditor 5:
721+
722+
```javascript
723+
beforeAll( () => {
724+
window.scrollTo = jest.fn();
725+
726+
window.ResizeObserver = class ResizeObserver {
727+
observe() {}
728+
unobserve() {}
729+
disconnect() {}
730+
};
731+
732+
for ( const key of [ 'InputEvent', 'KeyboardEvent' ] ) {
733+
window[ key ].prototype.getTargetRanges = () => {
734+
const range = new StaticRange( {
735+
startContainer: document.body.querySelector( '.ck-editor__editable p' ),
736+
startOffset: 0,
737+
endContainer: document.body.querySelector( '.ck-editor__editable p' ),
738+
endOffset: 0
739+
} );
740+
741+
return [ range ];
742+
};
743+
}
744+
745+
Range.prototype.getClientRects = () => ( {
746+
item: () => null,
747+
length: 0,
748+
[ Symbol.iterator ]: function* () {}
749+
} );
750+
} );
751+
```
752+
753+
These mocks should be placed before the tests that use CKEditor 5. They are imperfect and may not cover all the cases, but they should be sufficient for basic initialization and rendering editor. Keep in mind that they are not a replacement for proper browser testing.
754+
706755
## Contributing and reporting issues
707756

708757
The source code of the CKEditor 5 rich text editor component for Angular is available on GitHub in [https://github.com/ckeditor/ckeditor5-angular](https://github.com/ckeditor/ckeditor5-angular).

docs/getting-started/integrations/react.md

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,106 @@ export default App;
288288
289289
For more information, please refer to the {@link getting-started/setup/ui-language Setting the UI language} guide.
290290
291+
### Jest testing
292+
293+
Jest is the default test runner used by many React apps. Unfortunately, Jest does not use a real browser. Instead, it runs tests in Node.js that uses JSDOM. JSDOM is not a complete DOM implementation, and while it is sufficient for standard apps, it cannot polyfill all the DOM APIs that CKEditor 5 requires.
294+
295+
For testing CKEditor 5, it is recommended to use testing frameworks that utilize a real browser and provide a complete DOM implementation. Some popular options include:
296+
297+
* [Vitest](https://vitest.dev/)
298+
* [Playwright](https://playwright.dev/)
299+
* [Cypress](https://www.cypress.io/)
300+
301+
These frameworks offer better support for testing CKEditor 5 and provide a more accurate representation of how the editor behaves in a real browser environment.
302+
303+
If this is not possible and you still want to use Jest, you can mock some of the required APIs. Below is an example of how to mock some of the APIs used by CKEditor 5:
304+
305+
```jsx
306+
import React, { useRef } from 'react';
307+
import { render, waitFor, screen } from '@testing-library/react';
308+
import { userEvent } from '@testing-library/user-event';
309+
310+
import { DecoupledEditor, Essentials, Paragraph } from 'ckeditor5';
311+
import { CKEditor } from '@ckeditor/ckeditor5-react';
312+
313+
beforeAll( () => {
314+
window.scrollTo = jest.fn();
315+
316+
window.ResizeObserver = class ResizeObserver {
317+
observe() {}
318+
unobserve() {}
319+
disconnect() {}
320+
};
321+
322+
for ( const key of [ 'InputEvent', 'KeyboardEvent' ] ) {
323+
window[ key ].prototype.getTargetRanges = () => {
324+
const range = new StaticRange( {
325+
startContainer: document.body.querySelector( '.ck-editor__editable p' ),
326+
startOffset: 0,
327+
endContainer: document.body.querySelector( '.ck-editor__editable p' ),
328+
endOffset: 0
329+
} );
330+
331+
return [ range ];
332+
};
333+
}
334+
335+
Range.prototype.getClientRects = () => ( {
336+
item: () => null,
337+
length: 0,
338+
[ Symbol.iterator ]: function* () {}
339+
} );
340+
} );
341+
342+
const SomeComponent = ( { value, onChange } ) => {
343+
const editorRef = useRef();
344+
345+
return (
346+
<div
347+
style={{
348+
border: '1px solid black',
349+
padding: 10,
350+
}}
351+
>
352+
<CKEditor
353+
editor={ DecoupledEditor }
354+
config={{
355+
plugins: [ Essentials, Paragraph ],
356+
}}
357+
onReady={ (editor) => {
358+
editorRef.current = editor;
359+
} }
360+
data={ value }
361+
onChange={ () => {
362+
onChange( editorRef.current?.getData() );
363+
} }
364+
/>
365+
</div>
366+
);
367+
};
368+
369+
it( 'renders', async () => {
370+
render( <SomeComponent value="this is some content" /> );
371+
372+
await waitFor( () => expect( screen.getByText( /some content/ ) ).toBeTruthy());
373+
} );
374+
375+
it( 'updates', async () => {
376+
const onChange = jest.fn();
377+
render( <SomeComponent value="this is some content" onChange={onChange} /> );
378+
379+
await waitFor( () => expect( screen.getByText( /some content/ ) ).toBeTruthy() );
380+
381+
await userEvent.click( document.querySelector( '[contenteditable="true"]' ) );
382+
383+
userEvent.keyboard( 'more stuff' );
384+
385+
await waitFor( () => expect( onChange ).toHaveBeenCalled() );
386+
} );
387+
```
388+
389+
The mocks presented above only test two basic scenarios, and more will likely need to be added, which may change with each version of the editor.
390+
291391
## Contributing and reporting issues
292392
293393
The source code of rich text editor component for React is available on GitHub in [https://github.com/ckeditor/ckeditor5-react](https://github.com/ckeditor/ckeditor5-react).

docs/getting-started/integrations/vuejs-v3.md

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ Since accessing the editor toolbar is not possible until after the editor instan
400400
<script>
401401
import { DecoupledEditor, Bold, Essentials, Italic, Paragraph, Undo } from 'ckeditor5';
402402
import CKEditor from '@ckeditor/ckeditor5-vue';
403-
403+
404404
import 'ckeditor5/ckeditor5.css';
405405
406406
export default {
@@ -476,6 +476,53 @@ export default {
476476

477477
For more information, refer to the {@link getting-started/setup/ui-language Setting the UI language} guide.
478478

479+
### Jest testing
480+
481+
You can use Jest as a test runner in Vue apps. Unfortunately, Jest does not use a real browser. Instead, it runs tests in Node.js that uses JSDOM. JSDOM is not a complete DOM implementation, and while it is sufficient for standard apps, it cannot polyfill all the DOM APIs that CKEditor&nbsp;5 requires.
482+
483+
For testing CKEditor&nbsp;5, it is recommended to use testing frameworks that utilize a real browser and provide a complete DOM implementation. Some popular options include:
484+
485+
* [Vitest](https://vitest.dev/)
486+
* [Playwright](https://playwright.dev/)
487+
* [Cypress](https://www.cypress.io/)
488+
489+
These frameworks offer better support for testing CKEditor&nbsp;5 and provide a more accurate representation of how the editor behaves in a real browser environment.
490+
491+
If this is not possible and you still want to use Jest, you can mock some of the required APIs. Below is an example of how to mock some of the APIs used by CKEditor&nbsp;5:
492+
493+
```javascript
494+
beforeAll( () => {
495+
window.scrollTo = jest.fn();
496+
497+
window.ResizeObserver = class ResizeObserver {
498+
observe() {}
499+
unobserve() {}
500+
disconnect() {}
501+
};
502+
503+
for (const key of ['InputEvent', 'KeyboardEvent']) {
504+
window[key].prototype.getTargetRanges = () => {
505+
const range = new StaticRange({
506+
startContainer: document.body.querySelector('.ck-editor__editable p')!,
507+
startOffset: 0,
508+
endContainer: document.body.querySelector('.ck-editor__editable p')!,
509+
endOffset: 0,
510+
});
511+
512+
return [range];
513+
};
514+
}
515+
516+
Range.prototype.getClientRects = () => ({
517+
item: () => null,
518+
length: 0,
519+
[Symbol.iterator]: function* () {},
520+
});
521+
} );
522+
```
523+
524+
These mocks should be placed before the tests that use CKEditor&nbsp;5. They are imperfect and may not cover all the cases, but they should be sufficient for basic initialization and rendering editor. Remember that they are not a replacement for proper browser testing.
525+
479526
## Contributing and reporting issues
480527

481528
The source code of this component is available on GitHub in [https://github.com/ckeditor/ckeditor5-vue](https://github.com/ckeditor/ckeditor5-vue).

0 commit comments

Comments
 (0)