feat: Initial clean release of CHM
一些检查失败了
automerge / automerge (push) Has been cancelled
react-native-android-build-apk / AssembleRelease (push) Has been cancelled
Build macOS M1 / Main (push) Has been cancelled
Joplin Continuous Integration / Main (macos-15-intel) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-11-vs2026-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-2025) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04-arm) (push) Has been cancelled
Joplin UI tests / Main (ubuntu-22.04) (push) Has been cancelled
Joplin UI tests / Main (windows-2025) (push) Has been cancelled
Joplin UI tests / Mobile (push) Has been cancelled
Close stale issues / ProcessStaleIssues (push) Has been cancelled
一些检查失败了
automerge / automerge (push) Has been cancelled
react-native-android-build-apk / AssembleRelease (push) Has been cancelled
Build macOS M1 / Main (push) Has been cancelled
Joplin Continuous Integration / Main (macos-15-intel) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-11-vs2026-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-2025) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04-arm) (push) Has been cancelled
Joplin UI tests / Main (ubuntu-22.04) (push) Has been cancelled
Joplin UI tests / Main (windows-2025) (push) Has been cancelled
Joplin UI tests / Mobile (push) Has been cancelled
Close stale issues / ProcessStaleIssues (push) Has been cancelled
这个提交包含在:
@@ -0,0 +1,159 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import { describe, it, expect, beforeEach } from '@jest/globals';
|
||||
import { act, fireEvent, render, screen, waitFor } from '../../utils/testing/testingLibrary';
|
||||
|
||||
import NoteEditor from './NoteEditor';
|
||||
import Setting from '@joplin/lib/models/Setting';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
import { setupDatabaseAndSynchronizer, switchClient } from '@joplin/lib/testing/test-utils';
|
||||
import commandDeclarations from './commandDeclarations';
|
||||
import CommandService, { RegisteredRuntime } from '@joplin/lib/services/CommandService';
|
||||
import TestProviderStack from '../testing/TestProviderStack';
|
||||
import createMockReduxStore from '../../utils/testing/createMockReduxStore';
|
||||
import mockCommandRuntimes from '../EditorToolbar/testing/mockCommandRuntimes';
|
||||
import setupGlobalStore from '../../utils/testing/setupGlobalStore';
|
||||
import { Store } from 'redux';
|
||||
import { AppState } from '../../utils/types';
|
||||
import { MarkupLanguage } from '@joplin/renderer';
|
||||
import { EditorControl, EditorType } from './types';
|
||||
|
||||
let store: Store<AppState>;
|
||||
let registeredRuntime: RegisteredRuntime;
|
||||
|
||||
const defaultEditorProps = {
|
||||
themeId: Setting.THEME_ARITIM_DARK,
|
||||
markupLanguage: MarkupLanguage.Markdown,
|
||||
initialText: 'Testing...',
|
||||
globalSearch: '',
|
||||
noteId: '',
|
||||
noteHash: '',
|
||||
initialScroll: 0,
|
||||
style: {},
|
||||
toolbarEnabled: true,
|
||||
readOnly: false,
|
||||
onChange: ()=>{},
|
||||
onSelectionChange: ()=>{},
|
||||
onUndoRedoDepthChange: ()=>{},
|
||||
onScroll: ()=>{},
|
||||
onAttach: async ()=>{},
|
||||
onSearchVisibleChange: ()=>{},
|
||||
noteResources: {},
|
||||
plugins: {},
|
||||
mode: EditorType.Markdown,
|
||||
};
|
||||
|
||||
describe('NoteEditor', () => {
|
||||
beforeAll(() => {
|
||||
// This allows the NoteEditor test to register editor commands without errors.
|
||||
for (const declaration of commandDeclarations) {
|
||||
CommandService.instance().registerDeclaration(declaration);
|
||||
}
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
// Required to use ExtendedWebView
|
||||
await setupDatabaseAndSynchronizer(0);
|
||||
await switchClient(0);
|
||||
|
||||
store = createMockReduxStore();
|
||||
setupGlobalStore(store);
|
||||
registeredRuntime = mockCommandRuntimes(store);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
registeredRuntime.deregister();
|
||||
});
|
||||
|
||||
it('should provide an editor ref', () => {
|
||||
let editorRef: EditorControl;
|
||||
const onSetEditorRef = (ref: EditorControl) => {
|
||||
editorRef = ref;
|
||||
};
|
||||
|
||||
const wrappedNoteEditor = render(
|
||||
<TestProviderStack store={store}>
|
||||
<NoteEditor
|
||||
ref={onSetEditorRef}
|
||||
{...defaultEditorProps}
|
||||
mode={EditorType.RichText}
|
||||
/>
|
||||
</TestProviderStack>,
|
||||
);
|
||||
|
||||
expect(editorRef).toBeTruthy();
|
||||
|
||||
wrappedNoteEditor.unmount();
|
||||
});
|
||||
|
||||
it('should hide the markdown toolbar when the window is small', async () => {
|
||||
const wrappedNoteEditor = render(
|
||||
<TestProviderStack store={store}>
|
||||
<NoteEditor
|
||||
ref={undefined}
|
||||
{...defaultEditorProps}
|
||||
/>
|
||||
</TestProviderStack>,
|
||||
);
|
||||
|
||||
// Maps from screen height to whether the markdown toolbar should be visible.
|
||||
const testCases: [number, boolean][] = [
|
||||
[10, false],
|
||||
[1000, true],
|
||||
[100, false],
|
||||
[80, false],
|
||||
[600, true],
|
||||
];
|
||||
|
||||
const noteEditorRoot = await wrappedNoteEditor.findByTestId('note-editor-root');
|
||||
|
||||
const setRootHeight = (height: number) => {
|
||||
act(() => {
|
||||
// See https://stackoverflow.com/a/61774123
|
||||
fireEvent(noteEditorRoot, 'layout', {
|
||||
nativeEvent: {
|
||||
layout: { height },
|
||||
},
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
for (const [height, visible] of testCases) {
|
||||
setRootHeight(height);
|
||||
|
||||
await waitFor(async () => {
|
||||
const toolbarButton = await screen.queryByLabelText(_('Bold'));
|
||||
if (visible) {
|
||||
expect(toolbarButton).not.toBeNull();
|
||||
} else {
|
||||
expect(toolbarButton).toBeNull();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
wrappedNoteEditor.unmount();
|
||||
});
|
||||
|
||||
it('should show a warning banner the first time the Rich Text Editor is used', () => {
|
||||
const wrappedNoteEditor = render(
|
||||
<TestProviderStack store={store}>
|
||||
<NoteEditor
|
||||
ref={undefined}
|
||||
{...defaultEditorProps}
|
||||
mode={EditorType.RichText}
|
||||
/>
|
||||
</TestProviderStack>,
|
||||
);
|
||||
|
||||
const warningBannerQuery = /This Rich Text editor has a number of limitations.*/;
|
||||
const warning = screen.getByText(warningBannerQuery);
|
||||
expect(warning).toBeVisible();
|
||||
|
||||
// Pressing dismiss should dismiss the warning
|
||||
const dismissButton = screen.getByHintText('Hides warning');
|
||||
fireEvent.press(dismissButton);
|
||||
expect(screen.queryByText(warningBannerQuery)).toBeNull();
|
||||
|
||||
wrappedNoteEditor.unmount();
|
||||
});
|
||||
});
|
||||
在新工单中引用
屏蔽一个用户