From bd63a95848505d1fa1acb12b44ea48d5a4538a05 Mon Sep 17 00:00:00 2001 From: Mateusz Baginski Date: Fri, 13 Sep 2024 10:18:27 +0200 Subject: [PATCH 1/4] Make CDN configuration and result more narrow, bump commons package --- .circleci/config.yml | 5 +- .../ContextMultiRootEditorDemo.tsx | 2 +- .../MultiRootEditorDemo.tsx | 2 +- .../MultiRootEditorRichDemo.tsx | 2 +- .../useCKCdnMultiRootEditor.tsx | 4 +- demos/cdn-react/CKEditorCloudPluginsDemo.tsx | 2 +- .../ContextMultiRootEditorDemo.tsx | 2 +- .../MultiRootEditorDemo.tsx | 2 +- .../MultiRootEditorRichDemo.tsx | 2 +- package.json | 3 +- src/cloud/useCKEditorCloud.tsx | 23 +++-- src/cloud/withCKEditorCloud.tsx | 27 +++--- src/context/useInitializedCKEditorsMap.ts | 6 +- src/hooks/useAsyncCallback.ts | 4 +- src/hooks/useAsyncValue.ts | 4 +- src/hooks/useInstantEditorEffect.ts | 4 +- src/lifecycle/LifeCycleEditorSemaphore.ts | 2 +- tests/cloud/useCKEditorCloud.test.tsx | 83 ++++++++++++++++++- tests/context/ckeditorcontext.test.tsx | 4 +- tests/index.test.tsx | 8 +- .../ckeditor-classiceditor.test.tsx | 14 ++-- .../ckeditor-editor-data.test.tsx | 6 +- ...semultirooteditor-multirooteditor.test.tsx | 2 +- .../349-destroy-context-and-editor.test.tsx | 4 +- ...354-destroy-editor-inside-context.test.tsx | 6 +- ...er.test.tsx => 39-frozen-browser.test.tsx} | 4 +- tests/tsconfig.json | 2 + tests/useMultiRootEditor.test.tsx | 4 +- yarn.lock | 47 ++--------- 29 files changed, 163 insertions(+), 117 deletions(-) rename tests/issues/{39-frozen browser.test.tsx => 39-frozen-browser.test.tsx} (92%) diff --git a/.circleci/config.yml b/.circleci/config.yml index fdf39cc2..64c400d9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -114,6 +114,9 @@ jobs: - run: name: Run build command: yarn run build + - run: + name: Check types of tests + command: yarn run test:check:types - run: name: Run unit tests command: yarn run test @@ -205,7 +208,7 @@ jobs: name: Verify if a releaser triggered the job command: | #!/bin/bash - + # Do not fail if the Node script ends with non-zero exit code. set +e diff --git a/demos/cdn-multiroot-react/ContextMultiRootEditorDemo.tsx b/demos/cdn-multiroot-react/ContextMultiRootEditorDemo.tsx index 49cd45e2..ea8e5452 100644 --- a/demos/cdn-multiroot-react/ContextMultiRootEditorDemo.tsx +++ b/demos/cdn-multiroot-react/ContextMultiRootEditorDemo.tsx @@ -121,7 +121,7 @@ const ContextEditorDemo = ( { editor }: { editor: any } ): JSX.Element => { const withCKCloud = withCKEditorCloud( { cloud: { version: '43.0.0', - languages: [ 'en', 'de' ], + translations: [ 'en', 'de' ], premium: true } } ); diff --git a/demos/cdn-multiroot-react/MultiRootEditorDemo.tsx b/demos/cdn-multiroot-react/MultiRootEditorDemo.tsx index 7f2ea3ee..881081d2 100644 --- a/demos/cdn-multiroot-react/MultiRootEditorDemo.tsx +++ b/demos/cdn-multiroot-react/MultiRootEditorDemo.tsx @@ -20,7 +20,7 @@ type EditorDemoProps = WithCKEditorCloudHocProps & { const withCKCloud = withCKEditorCloud( { cloud: { version: '43.0.0', - languages: [ 'de' ], + translations: [ 'de' ], premium: true } } ); diff --git a/demos/cdn-multiroot-react/MultiRootEditorRichDemo.tsx b/demos/cdn-multiroot-react/MultiRootEditorRichDemo.tsx index 324656ed..8efbafe0 100644 --- a/demos/cdn-multiroot-react/MultiRootEditorRichDemo.tsx +++ b/demos/cdn-multiroot-react/MultiRootEditorRichDemo.tsx @@ -22,7 +22,7 @@ type EditorDemoProps = WithCKEditorCloudHocProps & { const withCKCloud = withCKEditorCloud( { cloud: { version: '43.0.0', - languages: [ 'de' ], + translations: [ 'de' ], premium: true } } ); diff --git a/demos/cdn-multiroot-react/useCKCdnMultiRootEditor.tsx b/demos/cdn-multiroot-react/useCKCdnMultiRootEditor.tsx index b156404e..6fabc135 100644 --- a/demos/cdn-multiroot-react/useCKCdnMultiRootEditor.tsx +++ b/demos/cdn-multiroot-react/useCKCdnMultiRootEditor.tsx @@ -4,9 +4,9 @@ */ import type { MultiRootEditor } from 'https://cdn.ckeditor.com/typings/ckeditor5.d.ts'; -import type { CKEditorCloudResult } from '../../src/index.js'; +import type { CKEditorCloudConfig, CKEditorCloudResult } from '../../src/index.js'; -export const useCKCdnMultiRootEditor = ( cloud: CKEditorCloudResult ): typeof MultiRootEditor => { +export const useCKCdnMultiRootEditor = ( cloud: CKEditorCloudResult ): typeof MultiRootEditor => { const { MultiRootEditor: MultiRootEditorBase, CloudServices, diff --git a/demos/cdn-react/CKEditorCloudPluginsDemo.tsx b/demos/cdn-react/CKEditorCloudPluginsDemo.tsx index cd3711df..d0eea0f0 100644 --- a/demos/cdn-react/CKEditorCloudPluginsDemo.tsx +++ b/demos/cdn-react/CKEditorCloudPluginsDemo.tsx @@ -23,7 +23,7 @@ declare global { export const CKEditorCloudPluginsDemo = ( { content }: CKEditorCloudPluginsDemoProps ): ReactNode => { const cloud = useCKEditorCloud( { version: '43.0.0', - languages: [ 'pl', 'de' ], + translations: [ 'pl', 'de' ], premium: true, plugins: { Wiris: { diff --git a/demos/npm-multiroot-react/ContextMultiRootEditorDemo.tsx b/demos/npm-multiroot-react/ContextMultiRootEditorDemo.tsx index 08de3298..45755f8e 100644 --- a/demos/npm-multiroot-react/ContextMultiRootEditorDemo.tsx +++ b/demos/npm-multiroot-react/ContextMultiRootEditorDemo.tsx @@ -6,7 +6,7 @@ import React from 'react'; import { useMultiRootEditor, type MultiRootHookProps, CKEditorContext } from '../../src/index.js'; -import MultiRootEditor from './MultiRootEditor'; +import MultiRootEditor from './MultiRootEditor.js'; export default function ContextMultiRootEditorDemo(): JSX.Element { return ( diff --git a/demos/npm-multiroot-react/MultiRootEditorDemo.tsx b/demos/npm-multiroot-react/MultiRootEditorDemo.tsx index e59510a7..379a8e3a 100644 --- a/demos/npm-multiroot-react/MultiRootEditorDemo.tsx +++ b/demos/npm-multiroot-react/MultiRootEditorDemo.tsx @@ -6,7 +6,7 @@ import React from 'react'; import { useMultiRootEditor, type MultiRootHookProps } from '../../src/index.js'; -import MultiRootEditor from './MultiRootEditor'; +import MultiRootEditor from './MultiRootEditor.js'; type EditorDemoProps = { data: Record; diff --git a/demos/npm-multiroot-react/MultiRootEditorRichDemo.tsx b/demos/npm-multiroot-react/MultiRootEditorRichDemo.tsx index 05cd86c7..cc229b4d 100644 --- a/demos/npm-multiroot-react/MultiRootEditorRichDemo.tsx +++ b/demos/npm-multiroot-react/MultiRootEditorRichDemo.tsx @@ -6,7 +6,7 @@ import React, { useState, type ChangeEvent } from 'react'; import { useMultiRootEditor, type MultiRootHookProps } from '../../src/index.js'; -import MultiRootEditor from './MultiRootEditor'; +import MultiRootEditor from './MultiRootEditor.js'; const SAMPLE_READ_ONLY_LOCK_ID = 'Integration Sample'; diff --git a/package.json b/package.json index 939e3b64..818be69d 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ }, "dependencies": { "prop-types": "^15.7.2", - "@ckeditor/ckeditor5-integrations-common": "^1.0.0" + "@ckeditor/ckeditor5-integrations-common": "^2.0.0" }, "peerDependencies": { "ckeditor5": ">=42.0.0 || ^0.0.0-nightly", @@ -91,6 +91,7 @@ "build": "vite build && tsc --emitDeclarationOnly", "test": "vitest run --coverage", "test:watch": "vitest --ui --watch", + "test:check:types": "tsc --noEmit -p ./tests/tsconfig.json", "lint": "eslint --quiet \"**/*.{ts,tsx}\"", "postinstall": "node ./scripts/postinstall.js", "changelog": "node ./scripts/changelog.js", diff --git a/src/cloud/useCKEditorCloud.tsx b/src/cloud/useCKEditorCloud.tsx index 4f8ef25d..b4b819a0 100644 --- a/src/cloud/useCKEditorCloud.tsx +++ b/src/cloud/useCKEditorCloud.tsx @@ -6,16 +6,15 @@ import { loadCKEditorCloud, type CKEditorCloudConfig, - type CKEditorCloudResult, - type CdnPluginsPacks + type CKEditorCloudResult } from '@ckeditor/ckeditor5-integrations-common'; -import { useAsyncValue, type AsyncValueHookResult } from '../hooks/useAsyncValue'; +import { useAsyncValue, type AsyncValueHookResult } from '../hooks/useAsyncValue.js'; /** * Hook that loads CKEditor bundles from CDN. * - * @template A The type of the additional resources to load. + * @template Config The type of the CKEditor Cloud configuration. * @param config The configuration of the hook. * @returns The state of async operation that resolves to the CKEditor bundles. * @example @@ -23,7 +22,7 @@ import { useAsyncValue, type AsyncValueHookResult } from '../hooks/useAsyncValue * ```ts * const cloud = useCKEditorCloud( { * version: '42.0.0', - * languages: [ 'en', 'de' ], + * translations: [ 'en', 'de' ], * premium: true * } ); * @@ -33,15 +32,15 @@ import { useAsyncValue, type AsyncValueHookResult } from '../hooks/useAsyncValue * } * ``` */ -export default function useCKEditorCloud( - config: CKEditorCloudConfig -): CKEditorCloudHookResult { +export default function useCKEditorCloud( + config: Config +): CKEditorCloudHookResult { // Serialize the config to a string to fast compare if there was a change and re-render is needed. const serializedConfigKey = JSON.stringify( config ); // Fetch the CKEditor Cloud Services bundles on every modification of config. const result = useAsyncValue( - async (): Promise> => loadCKEditorCloud( config ), + async (): Promise> => loadCKEditorCloud( config ), [ serializedConfigKey ] ); @@ -59,6 +58,6 @@ export default function useCKEditorCloud( /** * The result of the `useCKEditorCloud` hook. It changes success state to be more intuitive. */ -type CKEditorCloudHookResult = - | Exclude>, { status: 'success' }> - | ( CKEditorCloudResult & { status: 'success' } ); +type CKEditorCloudHookResult = + | Exclude>, { status: 'success' }> + | ( CKEditorCloudResult & { status: 'success' } ); diff --git a/src/cloud/withCKEditorCloud.tsx b/src/cloud/withCKEditorCloud.tsx index 09950b33..8ce2e162 100644 --- a/src/cloud/withCKEditorCloud.tsx +++ b/src/cloud/withCKEditorCloud.tsx @@ -6,11 +6,10 @@ import React, { type ReactNode, type ComponentType } from 'react'; import type { CKEditorCloudConfig, - CKEditorCloudResult, - CdnPluginsPacks + CKEditorCloudResult } from '@ckeditor/ckeditor5-integrations-common'; -import useCKEditorCloud from './useCKEditorCloud'; +import useCKEditorCloud from './useCKEditorCloud.js'; /** * HOC that injects the CKEditor Cloud integration into a component. @@ -24,7 +23,7 @@ import useCKEditorCloud from './useCKEditorCloud'; * const withCKCloud = withCKEditorCloud( { * cloud: { * version: '42.0.0', - * languages: [ 'en', 'de' ], + * translations: [ 'en', 'de' ], * premium: true * } * } ); @@ -38,11 +37,11 @@ import useCKEditorCloud from './useCKEditorCloud'; * } ); * ``` */ -const withCKEditorCloud = ( config: CKEditorCloudHocConfig ) => +const withCKEditorCloud = ( config: CKEditorCloudHocConfig ) =>

( - WrappedComponent: ComponentType & P> - ): ComponentType> => { - const ComponentWithCKEditorCloud = ( props: Omit ) => { + WrappedComponent: ComponentType & P> + ): ComponentType>> => { + const ComponentWithCKEditorCloud = ( props: Omit> ) => { const ckeditorCloudResult = useCKEditorCloud( config.cloud ); switch ( ckeditorCloudResult.status ) { @@ -74,27 +73,27 @@ export default withCKEditorCloud; /** * Props injected by the `withCKEditorCloud` HOC. * - * @template A The type of the additional resources to load. + * @template Config The configuration of the CKEditor Cloud integration. */ -export type WithCKEditorCloudHocProps = { +export type WithCKEditorCloudHocProps = { /** * The result of the CKEditor Cloud integration. */ - cloud: CKEditorCloudResult; + cloud: CKEditorCloudResult; }; /** * The configuration of the CKEditor Cloud integration. * - * @template A The type of the additional resources to load. + * @template Config The configuration of the CKEditor Cloud integration. */ -type CKEditorCloudHocConfig = { +type CKEditorCloudHocConfig = { /** * The configuration of the CKEditor Cloud integration. */ - cloud: CKEditorCloudConfig; + cloud: Config; /** * Component to render while the cloud information is being fetched. diff --git a/src/context/useInitializedCKEditorsMap.ts b/src/context/useInitializedCKEditorsMap.ts index 1d49b53b..14a62ffb 100644 --- a/src/context/useInitializedCKEditorsMap.ts +++ b/src/context/useInitializedCKEditorsMap.ts @@ -4,15 +4,15 @@ */ import { useEffect } from 'react'; -import { useRefSafeCallback } from '../hooks/useRefSafeCallback'; +import { useRefSafeCallback } from '../hooks/useRefSafeCallback.js'; import type { CollectionAddEvent, Context, ContextWatchdog, Editor } from 'ckeditor5'; -import type { ContextWatchdogValue } from './ckeditorcontext'; +import type { ContextWatchdogValue } from './ckeditorcontext.js'; import { tryExtractCKEditorReactContextMetadata, type CKEditorConfigContextMetadata -} from './setCKEditorReactContextMetadata'; +} from './setCKEditorReactContextMetadata.js'; /** * A hook that listens for the editor initialization and destruction events and updates the editors map. diff --git a/src/hooks/useAsyncCallback.ts b/src/hooks/useAsyncCallback.ts index 6c8b1f38..c962493c 100644 --- a/src/hooks/useAsyncCallback.ts +++ b/src/hooks/useAsyncCallback.ts @@ -6,8 +6,8 @@ import { useState, useRef } from 'react'; import { uid, isSSR } from '@ckeditor/ckeditor5-integrations-common'; -import { useIsUnmountedRef } from './useIsUnmountedRef'; -import { useRefSafeCallback } from './useRefSafeCallback'; +import { useIsUnmountedRef } from './useIsUnmountedRef.js'; +import { useRefSafeCallback } from './useRefSafeCallback.js'; /** * A hook that allows to execute an asynchronous function and provides the state of the execution. diff --git a/src/hooks/useAsyncValue.ts b/src/hooks/useAsyncValue.ts index 208f14f7..39f8b179 100644 --- a/src/hooks/useAsyncValue.ts +++ b/src/hooks/useAsyncValue.ts @@ -5,8 +5,8 @@ import type { DependencyList } from 'react'; -import { useInstantEffect } from './useInstantEffect'; -import { useAsyncCallback, type AsyncCallbackState } from './useAsyncCallback'; +import { useInstantEffect } from './useInstantEffect.js'; +import { useAsyncCallback, type AsyncCallbackState } from './useAsyncCallback.js'; /** * A hook that allows to execute an asynchronous function and provides the state of the execution. diff --git a/src/hooks/useInstantEditorEffect.ts b/src/hooks/useInstantEditorEffect.ts index 88759fa0..187e9c62 100644 --- a/src/hooks/useInstantEditorEffect.ts +++ b/src/hooks/useInstantEditorEffect.ts @@ -4,9 +4,9 @@ */ import type { DependencyList } from 'react'; -import type { LifeCycleElementSemaphore } from '../lifecycle/LifeCycleElementSemaphore'; +import type { LifeCycleElementSemaphore } from '../lifecycle/LifeCycleElementSemaphore.js'; -import { useInstantEffect } from './useInstantEffect'; +import { useInstantEffect } from './useInstantEffect.js'; /** * `useEffect` alternative but executed after mounting of editor. diff --git a/src/lifecycle/LifeCycleEditorSemaphore.ts b/src/lifecycle/LifeCycleEditorSemaphore.ts index 19f43293..4d1201a3 100644 --- a/src/lifecycle/LifeCycleEditorSemaphore.ts +++ b/src/lifecycle/LifeCycleEditorSemaphore.ts @@ -6,7 +6,7 @@ import type { Editor, EditorWatchdog } from 'ckeditor5'; import type { EditorWatchdogAdapter } from '../ckeditor'; -import type { LifeCycleElementSemaphore } from './LifeCycleElementSemaphore'; +import type { LifeCycleElementSemaphore } from './LifeCycleElementSemaphore.js'; export type EditorSemaphoreMountResult = { diff --git a/tests/cloud/useCKEditorCloud.test.tsx b/tests/cloud/useCKEditorCloud.test.tsx index 88e831da..96d4079e 100644 --- a/tests/cloud/useCKEditorCloud.test.tsx +++ b/tests/cloud/useCKEditorCloud.test.tsx @@ -3,13 +3,13 @@ * For licensing, see LICENSE.md. */ -import { beforeEach, describe, expect, it } from 'vitest'; +import { beforeEach, describe, expect, expectTypeOf, it } from 'vitest'; import { renderHook, waitFor, act } from '@testing-library/react'; import type { CKEditorCloudConfig } from '@ckeditor/ckeditor5-integrations-common'; import { removeAllCkCdnResources } from '@ckeditor/ckeditor5-integrations-common/test-utils'; -import useCKEditorCloud from '../../src/cloud/useCKEditorCloud'; +import useCKEditorCloud from '../../src/cloud/useCKEditorCloud.js'; describe( 'useCKEditorCloud', () => { beforeEach( removeAllCkCdnResources ); @@ -17,7 +17,7 @@ describe( 'useCKEditorCloud', () => { it( 'should load CKEditor bundles from CDN', async () => { const { result } = renderHook( () => useCKEditorCloud( { version: '43.0.0', - languages: [ 'en', 'de' ] + translations: [ 'en', 'de' ] } ) ); expect( result.current.status ).toBe( 'loading' ); @@ -69,4 +69,81 @@ describe( 'useCKEditorCloud', () => { } } ); } ); + + describe( 'typings', () => { + it( 'should return non-nullable premium features entry type if premium is enabled', async () => { + const { result } = renderHook( () => useCKEditorCloud( { + version: '43.0.0', + premium: true + } ) ); + + await waitFor( () => { + expect( result.current.status ).toBe( 'success' ); + } ); + + if ( result.current.status === 'success' ) { + expectTypeOf( result.current.CKEditorPremiumFeatures ).not.toBeNullable(); + } + } ); + + it( 'should return nullable premium features entry type if premium is disabled', async () => { + const { result } = renderHook( () => useCKEditorCloud( { + version: '43.0.0', + premium: false + } ) ); + + await waitFor( () => { + expect( result.current.status ).toBe( 'success' ); + } ); + + if ( result.current.status === 'success' ) { + expectTypeOf( result.current.CKEditorPremiumFeatures ).toBeNullable(); + } + } ); + + it( 'should return nullable premium features entry type if premium is not provided', async () => { + const { result } = renderHook( () => useCKEditorCloud( { + version: '43.0.0' + } ) ); + + await waitFor( () => { + expect( result.current.status ).toBe( 'success' ); + } ); + + if ( result.current.status === 'success' ) { + expectTypeOf( result.current.CKEditorPremiumFeatures ).toBeNullable(); + } + } ); + + it( 'should return non-nullable ckbox entry type if ckbox enabled', async () => { + const { result } = renderHook( () => useCKEditorCloud( { + version: '43.0.0', + ckbox: { + version: '2.5.1' + } + } ) ); + + await waitFor( () => { + expect( result.current.status ).toBe( 'success' ); + } ); + + if ( result.current.status === 'success' ) { + expectTypeOf( result.current.CKBox ).not.toBeNullable(); + } + } ); + + it( 'should return a nullable ckbox entry type if ckbox is not configured', async () => { + const { result } = renderHook( () => useCKEditorCloud( { + version: '43.0.0' + } ) ); + + await waitFor( () => { + expect( result.current.status ).toBe( 'success' ); + } ); + + if ( result.current.status === 'success' ) { + expectTypeOf( result.current.CKBox ).toBeNullable(); + } + } ); + } ); } ); diff --git a/tests/context/ckeditorcontext.test.tsx b/tests/context/ckeditorcontext.test.tsx index a86da6c0..7338c52e 100644 --- a/tests/context/ckeditorcontext.test.tsx +++ b/tests/context/ckeditorcontext.test.tsx @@ -11,9 +11,9 @@ import CKEditorContext, { type Props, type ContextWatchdogValue, type ExtractContextWatchdogValueByStatus -} from '../../src/context/ckeditorcontext.tsx'; +} from '../../src/context/ckeditorcontext.js'; -import CKEditor from '../../src/ckeditor.tsx'; +import CKEditor from '../../src/ckeditor.js'; import MockedEditor from '../_utils/editor.js'; import { ClassicEditor, ContextWatchdog, CKEditorError } from 'ckeditor5'; import turnOffDefaultErrorCatching from '../_utils/turnoffdefaulterrorcatching.js'; diff --git a/tests/index.test.tsx b/tests/index.test.tsx index 2df93053..09c877f4 100644 --- a/tests/index.test.tsx +++ b/tests/index.test.tsx @@ -7,10 +7,10 @@ import { describe, afterEach, it, expect, vi } from 'vitest'; import React from 'react'; import { ContextWatchdog } from 'ckeditor5'; import { render, type RenderResult } from '@testing-library/react'; -import ContextMock from './_utils/context.js'; -import Editor from './_utils/editor.js'; -import { PromiseManager } from './_utils/promisemanager.js'; -import { CKEditor, CKEditorContext } from '../src/index.js'; +import ContextMock from './_utils/context'; +import Editor from './_utils/editor'; +import { PromiseManager } from './_utils/promisemanager'; +import { CKEditor, CKEditorContext } from '../src/index'; const MockEditor = Editor as any; diff --git a/tests/integrations/ckeditor-classiceditor.test.tsx b/tests/integrations/ckeditor-classiceditor.test.tsx index 31208b4c..1d9cadd4 100644 --- a/tests/integrations/ckeditor-classiceditor.test.tsx +++ b/tests/integrations/ckeditor-classiceditor.test.tsx @@ -10,11 +10,11 @@ import React, { createRef } from 'react'; import ReactDOM from 'react-dom'; import { render, type RenderResult } from '@testing-library/react'; -import CKEditor from '../../src/ckeditor.tsx'; +import CKEditor from '../../src/ckeditor'; -import { timeout } from '../_utils/timeout.js'; +import { timeout } from '../_utils/timeout'; import { TestClassicEditor } from '../_utils/classiceditor.js'; -import { PromiseManager } from '../_utils/promisemanager.tsx'; +import { PromiseManager } from '../_utils/promisemanager.js'; describe( 'CKEditor Component + ClassicEditor Build', () => { let component: RenderResult | null = null; @@ -44,7 +44,6 @@ describe( 'CKEditor Component + ClassicEditor Build', () => { // The memory test based on: https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-core/tests/_utils/memory.js. // It's the simplified, adjusted version that allows checking whether the component destroys all references. -const TEST_RETRIES = 2; const TEST_TIMEOUT = 5000; const GARBAGE_COLLECTOR_TIMEOUT = 500; @@ -71,11 +70,8 @@ describe.skipIf( !window.gc || isWindows() )( ' memory usage', () => { // 3. Mount and unmount the component 5 times. // 4. Record the heap size and compare with the previous result. // 5. Fail when exceeded a 1MB treshold (see code comments for why 1MB). - it( 'should not grow on multiple component creations', function() { - this.timeout( TEST_TIMEOUT ); - - // Unfortunately the tests fails from time to time so retry a failed tests. - this.retries( TEST_RETRIES ); + it( 'should not grow on multiple component creations', async () => { + await timeout( TEST_TIMEOUT ); function createEditor() { div = document.createElement( 'div' ); diff --git a/tests/integrations/ckeditor-editor-data.test.tsx b/tests/integrations/ckeditor-editor-data.test.tsx index ad0735fa..13befb35 100644 --- a/tests/integrations/ckeditor-editor-data.test.tsx +++ b/tests/integrations/ckeditor-editor-data.test.tsx @@ -10,7 +10,7 @@ import { describe, beforeEach, afterEach, it, expect } from 'vitest'; import React from 'react'; import ReactDOM from 'react-dom'; -import CKEditor from '../../src/ckeditor.tsx'; +import CKEditor from '../../src/ckeditor.js'; import { TestClassicEditor } from '../_utils/classiceditor.js'; @@ -39,7 +39,7 @@ class AppUsingState extends React.Component { return ( this.setState( { content: editor.getData() } ) } + onChange={ ( _, editor ) => this.setState( { content: editor.getData() } ) } onReady={ editor => { this.editor = editor; this.props.onReady(); @@ -68,7 +68,7 @@ class AppUsingStaticString extends React.Component { return ( Initial data.

' } - onChange={ ( evt, editor ) => this.setState( { content: editor.getData() } ) } + onChange={ ( _, editor ) => this.setState( { content: editor.getData() } ) } onReady={ editor => { this.editor = editor; this.props.onReady(); diff --git a/tests/integrations/usemultirooteditor-multirooteditor.test.tsx b/tests/integrations/usemultirooteditor-multirooteditor.test.tsx index 3e070b1a..7a7a70f0 100644 --- a/tests/integrations/usemultirooteditor-multirooteditor.test.tsx +++ b/tests/integrations/usemultirooteditor-multirooteditor.test.tsx @@ -6,7 +6,7 @@ import { describe, beforeEach, it, expect } from 'vitest'; import React from 'react'; import { render, type RenderResult } from '@testing-library/react'; -import useMultiRootEditor from '../../src/useMultiRootEditor.tsx'; +import useMultiRootEditor from '../../src/useMultiRootEditor.js'; import { TestMultiRootEditor } from '../_utils/multirooteditor.js'; const AppUsingHooks = props => { diff --git a/tests/issues/349-destroy-context-and-editor.test.tsx b/tests/issues/349-destroy-context-and-editor.test.tsx index a59805d2..b266a27b 100644 --- a/tests/issues/349-destroy-context-and-editor.test.tsx +++ b/tests/issues/349-destroy-context-and-editor.test.tsx @@ -10,8 +10,8 @@ import React from 'react'; import { createRoot } from 'react-dom/client'; import { Context, ContextWatchdog } from 'ckeditor5'; -import CKEditor from '../../src/ckeditor.tsx'; -import CKEditorContext from '../../src/context/ckeditorcontext.tsx'; +import CKEditor from '../../src/ckeditor.js'; +import CKEditorContext from '../../src/context/ckeditorcontext.js'; import { TestClassicEditor } from '../_utils/classiceditor.js'; diff --git a/tests/issues/354-destroy-editor-inside-context.test.tsx b/tests/issues/354-destroy-editor-inside-context.test.tsx index c5b0c97e..d611cebb 100644 --- a/tests/issues/354-destroy-editor-inside-context.test.tsx +++ b/tests/issues/354-destroy-editor-inside-context.test.tsx @@ -7,10 +7,10 @@ import { describe, it, expect } from 'vitest'; import React from 'react'; import { Context, ContextWatchdog } from 'ckeditor5'; import { render, waitFor } from '@testing-library/react'; -import CKEditor from '../../src/ckeditor.tsx'; -import CKEditorContext from '../../src/context/ckeditorcontext.tsx'; +import CKEditor from '../../src/ckeditor.js'; +import CKEditorContext from '../../src/context/ckeditorcontext.js'; import { TestClassicEditor } from '../_utils/classiceditor.js'; -import { PromiseManager } from '../_utils/promisemanager.tsx'; +import { PromiseManager } from '../_utils/promisemanager.js'; class CustomContext extends Context {} diff --git a/tests/issues/39-frozen browser.test.tsx b/tests/issues/39-frozen-browser.test.tsx similarity index 92% rename from tests/issues/39-frozen browser.test.tsx rename to tests/issues/39-frozen-browser.test.tsx index dbd3aba0..f0008cd8 100644 --- a/tests/issues/39-frozen browser.test.tsx +++ b/tests/issues/39-frozen-browser.test.tsx @@ -9,7 +9,7 @@ import { describe, beforeEach, afterEach, it, expect } from 'vitest'; import React from 'react'; import ReactDOM from 'react-dom'; -import CKEditor from '../../src/ckeditor.tsx'; +import CKEditor from '../../src/ckeditor.js'; import { TestClassicEditor } from '../_utils/classiceditor.js'; @@ -36,7 +36,7 @@ class App extends React.Component { public render() { return ( this.setState( { content: editor.getData() } ) } + onChange={ ( _, editor ) => this.setState( { content: editor.getData() } ) } onReady={ editor => { this.editor = editor; this.props.onReady(); diff --git a/tests/tsconfig.json b/tests/tsconfig.json index dad543dc..8cc71761 100644 --- a/tests/tsconfig.json +++ b/tests/tsconfig.json @@ -1,6 +1,8 @@ { "extends": "../tsconfig.json", "compilerOptions": { + "emitDeclarationOnly": false, + "noImplicitAny": false, "types": [ "@testing-library/jest-dom/vitest", "../vite-env.d.ts" diff --git a/tests/useMultiRootEditor.test.tsx b/tests/useMultiRootEditor.test.tsx index a8bac928..31551a89 100644 --- a/tests/useMultiRootEditor.test.tsx +++ b/tests/useMultiRootEditor.test.tsx @@ -9,8 +9,8 @@ import { describe, beforeEach, afterEach, it, expect, vi } from 'vitest'; import React, { useEffect } from 'react'; import { CKEditorError } from 'ckeditor5'; import { render, waitFor, renderHook, act } from '@testing-library/react'; -import useMultiRootEditor, { EditorEditable, EditorToolbarWrapper } from '../src/useMultiRootEditor.tsx'; -import { ContextWatchdogContext } from '../src/context/ckeditorcontext.tsx'; +import useMultiRootEditor, { EditorEditable, EditorToolbarWrapper } from '../src/useMultiRootEditor.js'; +import { ContextWatchdogContext } from '../src/context/ckeditorcontext.js'; import { timeout } from './_utils/timeout.js'; import { createDefer } from './_utils/defer.js'; import { createTestMultiRootWatchdog, TestMultiRootEditor } from './_utils/multirooteditor.js'; diff --git a/yarn.lock b/yarn.lock index 9ef25a14..ab799d2e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1219,10 +1219,10 @@ "@ckeditor/ckeditor5-utils" "42.0.2" ckeditor5 "42.0.2" -"@ckeditor/ckeditor5-integrations-common@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-integrations-common/-/ckeditor5-integrations-common-1.0.0.tgz#f2f73509d029398929ee30da3ae23329de5a796a" - integrity sha512-HLToIJ7FAtKX0tu9GaGb1d39Kx0i0TFelAj2pQPiwPU/6DLgM5gi+m0WCZub+syruSonmZPONtWrrZZdUoDB/g== +"@ckeditor/ckeditor5-integrations-common@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-integrations-common/-/ckeditor5-integrations-common-2.0.0.tgz#09ea8a6a6a3c01f601260a85d9af98ede78644cf" + integrity sha512-Gkt7tYVv168voQZFdN4PxVp6M5/ZgzIOrqI6uPRjuk73dYjdLCeotnEXYejE6cxyLi9m2UM2mvhXibOIKVcoPw== "@ckeditor/ckeditor5-language@42.0.2": version "42.0.2" @@ -7880,7 +7880,7 @@ raw-loader@^4.0.1: loader-utils "^2.0.0" schema-utils "^3.0.0" -react-dom@^18.0.0: +react-dom@^18.0.0, "react18-dom@npm:react-dom@^18.0.0": version "18.3.1" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4" integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== @@ -7922,15 +7922,7 @@ react-refresh@^0.14.2: object-assign "^4.1.1" prop-types "^15.6.2" -"react18-dom@npm:react-dom@^18.0.0": - version "18.3.1" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4" - integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== - dependencies: - loose-envify "^1.1.0" - scheduler "^0.23.2" - -"react18@npm:react@^18.0.0": +"react18@npm:react@^18.0.0", react@^18.0.0: version "18.3.1" resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891" integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== @@ -7949,13 +7941,6 @@ react-refresh@^0.14.2: resolved "https://registry.yarnpkg.com/react/-/react-19.0.0-beta-26f2496093-20240514.tgz#3a0d63746b3f9ebd461a0731191bd08047fb1dbb" integrity sha512-ZsU/WjNZ6GfzMWsq2DcGjElpV9it8JmETHm9mAJuOJNhuJcWJxt8ltCJabONFRpDFq1A/DP0d0KFj9CTJVM4VA== -react@^18.0.0: - version "18.3.1" - resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891" - integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== - dependencies: - loose-envify "^1.1.0" - read-cache@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774" @@ -8748,7 +8733,7 @@ stringify-object@^3.3.0: is-obj "^1.0.1" is-regexp "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -8762,13 +8747,6 @@ strip-ansi@^5.2.0: dependencies: ansi-regex "^4.1.0" -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - strip-ansi@^7.0.1, strip-ansi@^7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" @@ -9573,16 +9551,7 @@ wordwrap@^1.0.0: resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@7.0.0, wrap-ansi@^6.2.0, wrap-ansi@^7.0.0, wrap-ansi@^8.0.1, wrap-ansi@^8.1.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@7.0.0, wrap-ansi@^6.2.0, wrap-ansi@^7.0.0, wrap-ansi@^8.0.1, wrap-ansi@^8.1.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== From 9a9f09709348611c912f2842b7a55990bf7b9f86 Mon Sep 17 00:00:00 2001 From: Mateusz Baginski Date: Fri, 13 Sep 2024 10:19:34 +0200 Subject: [PATCH 2/4] Fix imports --- tests/integrations/ckeditor-classiceditor.test.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/integrations/ckeditor-classiceditor.test.tsx b/tests/integrations/ckeditor-classiceditor.test.tsx index 1d9cadd4..5585d82f 100644 --- a/tests/integrations/ckeditor-classiceditor.test.tsx +++ b/tests/integrations/ckeditor-classiceditor.test.tsx @@ -10,9 +10,9 @@ import React, { createRef } from 'react'; import ReactDOM from 'react-dom'; import { render, type RenderResult } from '@testing-library/react'; -import CKEditor from '../../src/ckeditor'; +import CKEditor from '../../src/ckeditor.js'; -import { timeout } from '../_utils/timeout'; +import { timeout } from '../_utils/timeout.js'; import { TestClassicEditor } from '../_utils/classiceditor.js'; import { PromiseManager } from '../_utils/promisemanager.js'; From a6e259dd1d2566f460fdbc61bd0af38035a3de59 Mon Sep 17 00:00:00 2001 From: Mateusz Baginski Date: Fri, 13 Sep 2024 10:20:24 +0200 Subject: [PATCH 3/4] Fix langs in docs --- demos/cdn-multiroot-react/ContextMultiRootEditorDemo.tsx | 2 +- src/cloud/useCKEditorCloud.tsx | 2 +- src/cloud/withCKEditorCloud.tsx | 2 +- tests/cloud/useCKEditorCloud.test.tsx | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/demos/cdn-multiroot-react/ContextMultiRootEditorDemo.tsx b/demos/cdn-multiroot-react/ContextMultiRootEditorDemo.tsx index ea8e5452..4bc13033 100644 --- a/demos/cdn-multiroot-react/ContextMultiRootEditorDemo.tsx +++ b/demos/cdn-multiroot-react/ContextMultiRootEditorDemo.tsx @@ -121,7 +121,7 @@ const ContextEditorDemo = ( { editor }: { editor: any } ): JSX.Element => { const withCKCloud = withCKEditorCloud( { cloud: { version: '43.0.0', - translations: [ 'en', 'de' ], + translations: [ 'es', 'de' ], premium: true } } ); diff --git a/src/cloud/useCKEditorCloud.tsx b/src/cloud/useCKEditorCloud.tsx index b4b819a0..fd8ae753 100644 --- a/src/cloud/useCKEditorCloud.tsx +++ b/src/cloud/useCKEditorCloud.tsx @@ -22,7 +22,7 @@ import { useAsyncValue, type AsyncValueHookResult } from '../hooks/useAsyncValue * ```ts * const cloud = useCKEditorCloud( { * version: '42.0.0', - * translations: [ 'en', 'de' ], + * translations: [ 'es', 'de' ], * premium: true * } ); * diff --git a/src/cloud/withCKEditorCloud.tsx b/src/cloud/withCKEditorCloud.tsx index 8ce2e162..3cb7a054 100644 --- a/src/cloud/withCKEditorCloud.tsx +++ b/src/cloud/withCKEditorCloud.tsx @@ -23,7 +23,7 @@ import useCKEditorCloud from './useCKEditorCloud.js'; * const withCKCloud = withCKEditorCloud( { * cloud: { * version: '42.0.0', - * translations: [ 'en', 'de' ], + * translations: [ 'es', 'de' ], * premium: true * } * } ); diff --git a/tests/cloud/useCKEditorCloud.test.tsx b/tests/cloud/useCKEditorCloud.test.tsx index 96d4079e..fd0f92a6 100644 --- a/tests/cloud/useCKEditorCloud.test.tsx +++ b/tests/cloud/useCKEditorCloud.test.tsx @@ -17,7 +17,7 @@ describe( 'useCKEditorCloud', () => { it( 'should load CKEditor bundles from CDN', async () => { const { result } = renderHook( () => useCKEditorCloud( { version: '43.0.0', - translations: [ 'en', 'de' ] + translations: [ 'es', 'de' ] } ) ); expect( result.current.status ).toBe( 'loading' ); From 0800d8ee6ed23ac18798f903cc96919d9e5226fb Mon Sep 17 00:00:00 2001 From: Mateusz Baginski Date: Fri, 13 Sep 2024 10:22:12 +0200 Subject: [PATCH 4/4] Fix extensions --- tests/index.test.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/index.test.tsx b/tests/index.test.tsx index 09c877f4..2df93053 100644 --- a/tests/index.test.tsx +++ b/tests/index.test.tsx @@ -7,10 +7,10 @@ import { describe, afterEach, it, expect, vi } from 'vitest'; import React from 'react'; import { ContextWatchdog } from 'ckeditor5'; import { render, type RenderResult } from '@testing-library/react'; -import ContextMock from './_utils/context'; -import Editor from './_utils/editor'; -import { PromiseManager } from './_utils/promisemanager'; -import { CKEditor, CKEditorContext } from '../src/index'; +import ContextMock from './_utils/context.js'; +import Editor from './_utils/editor.js'; +import { PromiseManager } from './_utils/promisemanager.js'; +import { CKEditor, CKEditorContext } from '../src/index.js'; const MockEditor = Editor as any;