From bd31c8388c59f7426cedeb61bc12fc1458660467 Mon Sep 17 00:00:00 2001 From: L-Sun Date: Mon, 5 Aug 2024 03:57:48 +0000 Subject: [PATCH] fix(core): update outline viewer style (#7641) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What changes - Update responsive style and fix some bug of outline viewer (https://github.com/toeverything/blocksuite/pull/7759) - Change left and right padding of full-width editor from `15px` to `72px` - Hide outline viewer when side outline panel is opened ([BS-987](https://linear.app/affine-design/issue/BS-987/逻辑-bug-toc-入口和-toc-侧边栏共存)) - Add entries of outline panel and frame panel in more menu of detail page header ( [BS-996](https://linear.app/affine-design/issue/BS-996/page-mode-下的-page-option-缺少-view-table-of-contents-的入口) , [BS-1006](https://linear.app/affine-design/issue/BS-1006/edgeless-mode-的-page-options-里缺少-view-all-frames)) - Add outline viewer to dock peek preview ( [BS-995](https://linear.app/affine-design/issue/BS-995/center-peek-里缺少-quick-toc-的入口) ) - Add more e2e tests for outline viewer --- packages/common/env/package.json | 2 +- packages/common/infra/package.json | 2 +- packages/frontend/component/package.json | 2 +- packages/frontend/core/package.json | 2 +- .../block-suite-header/menu/index.tsx | 48 ++++++ .../blocksuite/outline-viewer/index.tsx} | 19 ++- .../outline-viewer/outline-viewer.css.ts | 17 +++ .../src/components/page-detail-editor.css.ts | 2 +- .../view/doc-preview/doc-peek-view.css.ts | 4 + .../view/doc-preview/doc-peek-view.tsx | 20 ++- .../workspace/detail-page/detail-page.css.ts | 1 + .../workspace/detail-page/detail-page.tsx | 22 +-- .../detail-page/outline-viewer.css.ts | 8 - packages/frontend/electron/package.json | 2 +- packages/frontend/i18n/src/resources/en.json | 2 + .../e2e/blocksuite/editor.spec.ts | 47 ------ .../e2e/blocksuite/outline.spec.ts | 143 ++++++++++++++++++ tools/cli/package.json | 2 +- 18 files changed, 264 insertions(+), 81 deletions(-) rename packages/frontend/core/src/{pages/workspace/detail-page/outline-viewer.tsx => components/blocksuite/outline-viewer/index.tsx} (70%) create mode 100644 packages/frontend/core/src/components/blocksuite/outline-viewer/outline-viewer.css.ts delete mode 100644 packages/frontend/core/src/pages/workspace/detail-page/outline-viewer.css.ts create mode 100644 tests/affine-local/e2e/blocksuite/outline.spec.ts diff --git a/packages/common/env/package.json b/packages/common/env/package.json index 803e36720d..cd694ddb07 100644 --- a/packages/common/env/package.json +++ b/packages/common/env/package.json @@ -27,4 +27,4 @@ "zod": "^3.22.4" }, "version": "0.15.0" -} +} \ No newline at end of file diff --git a/packages/common/infra/package.json b/packages/common/infra/package.json index 9e1430e0c1..b16510f66e 100644 --- a/packages/common/infra/package.json +++ b/packages/common/infra/package.json @@ -74,4 +74,4 @@ } }, "version": "0.15.0" -} +} \ No newline at end of file diff --git a/packages/frontend/component/package.json b/packages/frontend/component/package.json index 3ab57f7ecc..934965fe7c 100644 --- a/packages/frontend/component/package.json +++ b/packages/frontend/component/package.json @@ -111,4 +111,4 @@ "vitest": "1.6.0" }, "version": "0.15.0" -} +} \ No newline at end of file diff --git a/packages/frontend/core/package.json b/packages/frontend/core/package.json index e8fbc17943..a15b08d639 100644 --- a/packages/frontend/core/package.json +++ b/packages/frontend/core/package.json @@ -116,4 +116,4 @@ "mime-types": "^2.1.35", "vitest": "1.6.0" } -} +} \ No newline at end of file diff --git a/packages/frontend/core/src/components/blocksuite/block-suite-header/menu/index.tsx b/packages/frontend/core/src/components/blocksuite/block-suite-header/menu/index.tsx index 511a0dcfe3..1a84e8c261 100644 --- a/packages/frontend/core/src/components/blocksuite/block-suite-header/menu/index.tsx +++ b/packages/frontend/core/src/components/blocksuite/block-suite-header/menu/index.tsx @@ -20,6 +20,7 @@ import { useTrashModalHelper } from '@affine/core/hooks/affine/use-trash-modal-h import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks'; import { mixpanel } from '@affine/core/mixpanel'; import { WorkbenchService } from '@affine/core/modules/workbench'; +import { ViewService } from '@affine/core/modules/workbench/services/view'; import { useDetailPageHeaderResponsive } from '@affine/core/pages/workspace/detail-page/use-header-responsive'; import { WorkspaceFlavour } from '@affine/env/workspace'; import { useI18n } from '@affine/i18n'; @@ -29,6 +30,7 @@ import { EditIcon, FavoritedIcon, FavoriteIcon, + FrameIcon, HistoryIcon, ImportIcon, InformationIcon, @@ -36,6 +38,7 @@ import { PageIcon, ShareIcon, SplitViewIcon, + TocIcon, } from '@blocksuite/icons/rc'; import type { Doc } from '@blocksuite/store'; import { @@ -84,6 +87,24 @@ export const PageHeaderMenuButton = ({ const { importFile } = usePageHelper(docCollection); const { setTrashModal } = useTrashModalHelper(docCollection); + const view = useService(ViewService).view; + + const openSidePanel = useCallback( + (id: string) => { + workbench.openSidebar(); + view.activeSidebarTab(id); + }, + [workbench, view] + ); + + const openAllFrames = useCallback(() => { + openSidePanel('frame'); + }, [openSidePanel]); + + const openOutlinePanel = useCallback(() => { + openSidePanel('outline'); + }, [openSidePanel]); + const [historyModalOpen, setHistoryModalOpen] = useState(false); const setOpenHistoryTipsModal = useSetAtom(openHistoryTipsModalAtom); @@ -297,6 +318,33 @@ export const PageHeaderMenuButton = ({ {t['com.affine.page-properties.page-info.view']()} )} + {currentMode === 'page' ? ( + + + + } + data-testid="editor-option-toc" + onSelect={openOutlinePanel} + style={menuItemStyle} + > + {t['com.affine.header.option.view-toc']()} + + ) : ( + + + + } + data-testid="editor-option-frame" + onSelect={openAllFrames} + style={menuItemStyle} + > + {t['com.affine.header.option.view-frame']()} + + )} diff --git a/packages/frontend/core/src/pages/workspace/detail-page/outline-viewer.tsx b/packages/frontend/core/src/components/blocksuite/outline-viewer/index.tsx similarity index 70% rename from packages/frontend/core/src/pages/workspace/detail-page/outline-viewer.tsx rename to packages/frontend/core/src/components/blocksuite/outline-viewer/index.tsx index ca760f693f..b7d28ced5e 100644 --- a/packages/frontend/core/src/pages/workspace/detail-page/outline-viewer.tsx +++ b/packages/frontend/core/src/components/blocksuite/outline-viewer/index.tsx @@ -6,10 +6,12 @@ import * as styles from './outline-viewer.css'; export const EditorOutlineViewer = ({ editor, - toggleOutlinePanel, + show, + openOutlinePanel, }: { editor: AffineEditorContainer | null; - toggleOutlinePanel: () => void; + show: boolean; + openOutlinePanel: () => void; }) => { const outlineViewerRef = useRef(null); @@ -24,15 +26,16 @@ export const EditorOutlineViewer = ({ } }, []); - if (!editor) { - return; - } + if (!editor || !show) return; if (!outlineViewerRef.current) { outlineViewerRef.current = new OutlineViewer(); - (outlineViewerRef.current as OutlineViewer).editor = editor; - (outlineViewerRef.current as OutlineViewer).toggleOutlinePanel = - toggleOutlinePanel; + } + if (outlineViewerRef.current.editor !== editor) { + outlineViewerRef.current.editor = editor; + } + if (outlineViewerRef.current.toggleOutlinePanel !== openOutlinePanel) { + outlineViewerRef.current.toggleOutlinePanel = openOutlinePanel; } return
; diff --git a/packages/frontend/core/src/components/blocksuite/outline-viewer/outline-viewer.css.ts b/packages/frontend/core/src/components/blocksuite/outline-viewer/outline-viewer.css.ts new file mode 100644 index 0000000000..b6705bd565 --- /dev/null +++ b/packages/frontend/core/src/components/blocksuite/outline-viewer/outline-viewer.css.ts @@ -0,0 +1,17 @@ +import { style } from '@vanilla-extract/css'; + +const top = 256 - 52; // 52 is the height of the header +const bottom = 76; + +export const root = style({ + position: 'absolute', + top, + right: 22, + maxHeight: `calc(100% - ${top}px - ${bottom}px)`, + display: 'flex', + '@container': { + '(width <= 640px)': { + display: 'none', + }, + }, +}); diff --git a/packages/frontend/core/src/components/page-detail-editor.css.ts b/packages/frontend/core/src/components/page-detail-editor.css.ts index c71f70ddda..567cca65c3 100644 --- a/packages/frontend/core/src/components/page-detail-editor.css.ts +++ b/packages/frontend/core/src/components/page-detail-editor.css.ts @@ -5,7 +5,7 @@ export const editor = style({ '&.full-screen': { vars: { '--affine-editor-width': '100%', - '--affine-editor-side-padding': '15px', + '--affine-editor-side-padding': '72px', }, }, }, diff --git a/packages/frontend/core/src/modules/peek-view/view/doc-preview/doc-peek-view.css.ts b/packages/frontend/core/src/modules/peek-view/view/doc-preview/doc-peek-view.css.ts index 7fb09c3ea2..fab83c13ea 100644 --- a/packages/frontend/core/src/modules/peek-view/view/doc-preview/doc-peek-view.css.ts +++ b/packages/frontend/core/src/modules/peek-view/view/doc-preview/doc-peek-view.css.ts @@ -1,6 +1,10 @@ import { cssVar } from '@toeverything/theme'; import { style } from '@vanilla-extract/css'; +export const root = style({ + containerType: 'inline-size', +}); + export const editor = style({ vars: { '--affine-editor-width': '100%', diff --git a/packages/frontend/core/src/modules/peek-view/view/doc-preview/doc-peek-view.tsx b/packages/frontend/core/src/modules/peek-view/view/doc-preview/doc-peek-view.tsx index bc90b95d1c..26143153c5 100644 --- a/packages/frontend/core/src/modules/peek-view/view/doc-preview/doc-peek-view.tsx +++ b/packages/frontend/core/src/modules/peek-view/view/doc-preview/doc-peek-view.tsx @@ -3,6 +3,8 @@ import { PageDetailSkeleton } from '@affine/component/page-detail-skeleton'; import { AIProvider } from '@affine/core/blocksuite/presets/ai'; import { AffineErrorBoundary } from '@affine/core/components/affine/affine-error-boundary'; import { BlockSuiteEditor } from '@affine/core/components/blocksuite/block-suite-editor'; +import { EditorOutlineViewer } from '@affine/core/components/blocksuite/outline-viewer'; +import { useAppSettingHelper } from '@affine/core/hooks/affine/use-app-setting-helper'; import { useNavigateHelper } from '@affine/core/hooks/use-navigate-helper'; import { PageNotFound } from '@affine/core/pages/404'; import { DebugLogger } from '@affine/debug'; @@ -12,7 +14,7 @@ import type { AffineEditorContainer } from '@blocksuite/presets'; import type { DocMode } from '@toeverything/infra'; import { DocsService, FrameworkScope, useService } from '@toeverything/infra'; import clsx from 'clsx'; -import { useEffect, useState } from 'react'; +import { useCallback, useEffect, useState } from 'react'; import { WorkbenchService } from '../../../workbench'; import { PeekViewService } from '../../services/peek-view'; @@ -73,6 +75,7 @@ export function DocPeekPreview({ const workbench = useService(WorkbenchService).workbench; const peekView = useService(PeekViewService).peekView; const [editor, setEditor] = useState(null); + const { appSettings } = useAppSettingHelper(); const onRef = (editor: AffineEditorContainer) => { setEditor(editor); @@ -143,6 +146,13 @@ export function DocPeekPreview({ }; }, [editor, jumpToTag, peekView, workspace.id]); + const openOutlinePanel = useCallback(() => { + workbench.openDoc(docId); + workbench.openSidebar(); + workbench.activeView$.value.activeSidebarTab('outline'); + peekView.close(); + }, [docId, peekView, workbench]); + // if sync engine has been synced and the page is null, show 404 page. if (!doc || !resolvedMode) { return loading || !resolvedMode ? ( @@ -167,7 +177,15 @@ export function DocPeekPreview({ page={doc.blockSuiteDoc} /> + {appSettings.enableOutlineViewer && ( + + )} + diff --git a/packages/frontend/core/src/pages/workspace/detail-page/detail-page.css.ts b/packages/frontend/core/src/pages/workspace/detail-page/detail-page.css.ts index 24a179cc88..d6d8985c1a 100644 --- a/packages/frontend/core/src/pages/workspace/detail-page/detail-page.css.ts +++ b/packages/frontend/core/src/pages/workspace/detail-page/detail-page.css.ts @@ -2,6 +2,7 @@ import { cssVar } from '@toeverything/theme'; import { style } from '@vanilla-extract/css'; export const mainContainer = style({ + containerType: 'inline-size', display: 'flex', flexDirection: 'column', flex: 1, diff --git a/packages/frontend/core/src/pages/workspace/detail-page/detail-page.tsx b/packages/frontend/core/src/pages/workspace/detail-page/detail-page.tsx index 69de5bde11..cb877f9731 100644 --- a/packages/frontend/core/src/pages/workspace/detail-page/detail-page.tsx +++ b/packages/frontend/core/src/pages/workspace/detail-page/detail-page.tsx @@ -3,6 +3,7 @@ import { PageDetailSkeleton } from '@affine/component/page-detail-skeleton'; import type { ChatPanel } from '@affine/core/blocksuite/presets/ai'; import { AIProvider } from '@affine/core/blocksuite/presets/ai'; import { PageAIOnboarding } from '@affine/core/components/affine/ai-onboarding'; +import { EditorOutlineViewer } from '@affine/core/components/blocksuite/outline-viewer'; import { useAppSettingHelper } from '@affine/core/hooks/affine/use-app-setting-helper'; import { useDocMetaHelper } from '@affine/core/hooks/use-block-suite-page-meta'; import { RecentDocsService } from '@affine/core/modules/quicksearch'; @@ -64,7 +65,6 @@ import { performanceRenderLogger } from '../../../shared'; import { PageNotFound } from '../../404'; import * as styles from './detail-page.css'; import { DetailPageHeader } from './detail-page-header'; -import { EditorOutlineViewer } from './outline-viewer'; import { EditorChatPanel } from './tabs/chat'; import { EditorFramePanel } from './tabs/frame'; import { EditorJournalPanel } from './tabs/journal'; @@ -83,6 +83,7 @@ const DetailPageImpl = memo(function DetailPageImpl() { const globalContext = useService(GlobalContextService).globalContext; const docCollection = workspace.docCollection; const mode = useLiveData(doc.mode$); + const isSideBarOpen = useLiveData(workbench.sidebarOpen$); const { appSettings } = useAppSettingHelper(); const chatPanelRef = useRef(null); const { setDocReadonly } = useDocMetaHelper(workspace.docCollection); @@ -226,14 +227,14 @@ const DetailPageImpl = memo(function DetailPageImpl() { [jumpToPageBlock, docCollection.id, openPage, jumpToTag, workspace.id] ); + const [refCallback, hasScrollTop] = useHasScrollTop(); + const dynamicTopBorder = environment.isDesktop; + const openOutlinePanel = useCallback(() => { workbench.openSidebar(); view.activeSidebarTab('outline'); }, [workbench, view]); - const [refCallback, hasScrollTop] = useHasScrollTop(); - const dynamicTopBorder = environment.isDesktop; - return ( <> @@ -269,15 +270,16 @@ const DetailPageImpl = memo(function DetailPageImpl() { })} /> + {appSettings.enableOutlineViewer && ( + + )} {isInTrash ? : null}
- {appSettings.enableOutlineViewer && ( - - )} } unmountOnInactive={false}> diff --git a/packages/frontend/core/src/pages/workspace/detail-page/outline-viewer.css.ts b/packages/frontend/core/src/pages/workspace/detail-page/outline-viewer.css.ts deleted file mode 100644 index d58b79f3da..0000000000 --- a/packages/frontend/core/src/pages/workspace/detail-page/outline-viewer.css.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { style } from '@vanilla-extract/css'; - -export const root = style({ - position: 'fixed', - top: 256, - right: 22, - maxHeight: 'calc(100% - 16px)', -}); diff --git a/packages/frontend/electron/package.json b/packages/frontend/electron/package.json index ef1a8d451d..963b562aa5 100644 --- a/packages/frontend/electron/package.json +++ b/packages/frontend/electron/package.json @@ -95,4 +95,4 @@ "peerDependencies": { "ts-node": "*" } -} +} \ No newline at end of file diff --git a/packages/frontend/i18n/src/resources/en.json b/packages/frontend/i18n/src/resources/en.json index 72966dae39..90601046cd 100644 --- a/packages/frontend/i18n/src/resources/en.json +++ b/packages/frontend/i18n/src/resources/en.json @@ -719,6 +719,8 @@ "com.affine.filterList.button.add": "Add Filter", "com.affine.header.option.add-tag": "Add Tag", "com.affine.header.option.duplicate": "Duplicate", + "com.affine.header.option.view-toc": "View table of contents", + "com.affine.header.option.view-frame": "View all frames", "com.affine.helpIsland.contactUs": "Contact us", "com.affine.helpIsland.gettingStarted": "Getting started", "com.affine.helpIsland.helpAndFeedback": "Help and Feedback", diff --git a/tests/affine-local/e2e/blocksuite/editor.spec.ts b/tests/affine-local/e2e/blocksuite/editor.spec.ts index 5df79cc5a7..40b4e0568f 100644 --- a/tests/affine-local/e2e/blocksuite/editor.spec.ts +++ b/tests/affine-local/e2e/blocksuite/editor.spec.ts @@ -5,11 +5,6 @@ import { getBlockSuiteEditorTitle, waitForEditorLoad, } from '@affine-test/kit/utils/page-logic'; -import { - confirmExperimentalPrompt, - openExperimentalFeaturesPanel, - openSettingModal, -} from '@affine-test/kit/utils/setting'; import type { Page } from '@playwright/test'; import { expect } from '@playwright/test'; @@ -78,45 +73,3 @@ test('link page is useable', async ({ page }) => { page.locator('.doc-title-container:has-text("page1")') ).toBeVisible(); }); - -test('outline viewer is useable', async ({ page }) => { - await openHomePage(page); - await waitForEditorLoad(page); - await clickNewPageButton(page); - await waitForEditorLoad(page); - - await openSettingModal(page); - await openExperimentalFeaturesPanel(page); - const prompt = page.getByTestId('experimental-prompt'); - await expect(prompt).toBeVisible(); - await confirmExperimentalPrompt(page); - const settings = page.getByTestId('experimental-settings'); - const enableOutlineViewerSetting = settings.getByTestId( - 'outline-viewer-switch' - ); - await expect(enableOutlineViewerSetting).toBeVisible(); - await enableOutlineViewerSetting.click(); - await page.waitForTimeout(500); - await page.getByTestId('modal-close-button').click(); - await page.waitForTimeout(500); - - const title = getBlockSuiteEditorTitle(page); - await title.pressSequentially('Title'); - await page.keyboard.press('Enter'); - expect(await title.innerText()).toBe('Title'); - await page.keyboard.type('# '); - await page.keyboard.type('Heading 1'); - await page.keyboard.press('Enter'); - await page.keyboard.type('## '); - await page.keyboard.type('Heading 2'); - await page.keyboard.press('Enter'); - - const indicators = page.locator('.outline-heading-indicator'); - await expect(indicators).toHaveCount(2); - await expect(indicators.nth(0)).toBeVisible(); - await expect(indicators.nth(1)).toBeVisible(); - - const viewer = page.locator('affine-outline-panel-body'); - await indicators.first().hover({ force: true }); - await expect(viewer).toBeVisible(); -}); diff --git a/tests/affine-local/e2e/blocksuite/outline.spec.ts b/tests/affine-local/e2e/blocksuite/outline.spec.ts new file mode 100644 index 0000000000..f9d84d2310 --- /dev/null +++ b/tests/affine-local/e2e/blocksuite/outline.spec.ts @@ -0,0 +1,143 @@ +import { test } from '@affine-test/kit/playwright'; +import { + clickEdgelessModeButton, + clickPageModeButton, +} from '@affine-test/kit/utils/editor'; +import { openHomePage } from '@affine-test/kit/utils/load-page'; +import { + clickNewPageButton, + createLinkedPage, + getBlockSuiteEditorTitle, + waitForEditorLoad, + waitForEmptyEditor, +} from '@affine-test/kit/utils/page-logic'; +import { + confirmExperimentalPrompt, + openExperimentalFeaturesPanel, + openSettingModal, +} from '@affine-test/kit/utils/setting'; +import { expect, type Page } from '@playwright/test'; + +async function enableOutlineViewer(page: Page) { + await openSettingModal(page); + await openExperimentalFeaturesPanel(page); + const prompt = page.getByTestId('experimental-prompt'); + await expect(prompt).toBeVisible(); + await confirmExperimentalPrompt(page); + const settings = page.getByTestId('experimental-settings'); + const enableOutlineViewerSetting = settings.getByTestId( + 'outline-viewer-switch' + ); + await expect(enableOutlineViewerSetting).toBeVisible(); + await enableOutlineViewerSetting.click(); + await page.waitForTimeout(500); + await page.getByTestId('modal-close-button').click(); + await page.waitForTimeout(500); +} + +test('outline viewer is useable', async ({ page }) => { + await openHomePage(page); + await waitForEditorLoad(page); + await clickNewPageButton(page); + await waitForEditorLoad(page); + await enableOutlineViewer(page); + + const title = getBlockSuiteEditorTitle(page); + await title.click(); + await title.pressSequentially('Title'); + await expect(title).toContainText('Title'); + await page.keyboard.press('Enter'); + await page.keyboard.type('# '); + await page.keyboard.type('Heading 1'); + await page.keyboard.press('Enter'); + await page.keyboard.type('## '); + await page.keyboard.type('Heading 2'); + await page.keyboard.press('Enter'); + + const indicators = page.locator('.outline-heading-indicator'); + await expect(indicators).toHaveCount(2); + await expect(indicators.nth(0)).toBeVisible(); + await expect(indicators.nth(1)).toBeVisible(); + + const viewer = page.locator('affine-outline-panel-body'); + await indicators.first().hover({ force: true }); + await expect(viewer).toBeVisible(); +}); + +test('outline viewer should hide in edgeless mode', async ({ page }) => { + await openHomePage(page); + await waitForEditorLoad(page); + await clickNewPageButton(page); + await waitForEditorLoad(page); + await enableOutlineViewer(page); + + const title = getBlockSuiteEditorTitle(page); + await title.click(); + await title.pressSequentially('Title'); + await page.keyboard.press('Enter'); + await expect(title).toHaveText('Title'); + await page.keyboard.type('# '); + await page.keyboard.type('Heading 1'); + + const indicators = page.locator('.outline-heading-indicator'); + await expect(indicators).toHaveCount(1); + + await clickEdgelessModeButton(page); + await expect(indicators).toHaveCount(0); + + await clickPageModeButton(page); + await expect(indicators).toHaveCount(1); +}); + +test('outline viewer should be useable in doc peek preview', async ({ + page, +}) => { + await openHomePage(page); + await waitForEditorLoad(page); + await enableOutlineViewer(page); + await clickNewPageButton(page); + await waitForEmptyEditor(page); + + await page.keyboard.press('Enter'); + await createLinkedPage(page, 'Test Page'); + + await page.locator('affine-reference').hover(); + + await expect( + page.locator('.affine-reference-popover-container') + ).toBeVisible(); + + await page + .locator('editor-menu-button editor-icon-button[aria-label="Open doc"]') + .click(); + await page + .locator('editor-menu-action:has-text("Open in center peek")') + .click(); + + const peekView = page.getByTestId('peek-view-modal'); + await expect(peekView).toBeVisible(); + + const title = peekView.locator('doc-title .inline-editor'); + await title.click(); + await page.keyboard.press('Enter'); + + await page.keyboard.type('# Heading 1'); + + const indicators = peekView.locator('.outline-heading-indicator'); + await expect(indicators).toHaveCount(1); + await expect(indicators).toBeVisible(); + + await indicators.first().hover({ force: true }); + const viewer = peekView.locator('affine-outline-panel-body'); + await expect(viewer).toBeVisible(); + + const toggleButton = peekView.locator( + '.outline-viewer-header-container edgeless-tool-icon-button' + ); + await toggleButton.click(); + + await page.waitForTimeout(500); + await expect(peekView).toBeHidden(); + await expect(viewer).toBeHidden(); + await expect(page.locator('affine-outline-panel')).toBeVisible(); +}); diff --git a/tools/cli/package.json b/tools/cli/package.json index d85c103ad3..df19bd66a2 100644 --- a/tools/cli/package.json +++ b/tools/cli/package.json @@ -46,4 +46,4 @@ "dev": "node --loader ts-node/esm/transpile-only.mjs ./src/bin/dev.ts" }, "version": "0.15.0" -} +} \ No newline at end of file