diff --git a/packages/frontend/core/src/components/blocksuite/block-suite-editor/lit-adaper.tsx b/packages/frontend/core/src/components/blocksuite/block-suite-editor/lit-adaper.tsx
index 7f602b57bc..43c027fc8a 100644
--- a/packages/frontend/core/src/components/blocksuite/block-suite-editor/lit-adaper.tsx
+++ b/packages/frontend/core/src/components/blocksuite/block-suite-editor/lit-adaper.tsx
@@ -97,9 +97,7 @@ const usePatchSpecs = (page: Doc, shared: boolean, mode: DocMode) => {
patchReferenceRenderer(patched, reactToLit, referenceRenderer),
confirmModal
);
- if (!page.readonly) {
- patched = patchPeekViewService(patched, peekViewService);
- }
+ patched = patchPeekViewService(patched, peekViewService);
if (!page.readonly) {
patched = patchQuickSearchService(patched, framework);
}
diff --git a/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/custom/spec-patchers.tsx b/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/custom/spec-patchers.tsx
index 69089f834b..7473ffc1d8 100644
--- a/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/custom/spec-patchers.tsx
+++ b/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/custom/spec-patchers.tsx
@@ -514,7 +514,7 @@ export function patchQuickSearchService(
@customElement('affine-linked-doc-ref-block')
// @ts-expect-error ignore private warning for overriding _load
export class LinkedDocBlockComponent extends EmbedLinkedDocBlockComponent {
- override _load() {
+ override async _load() {
this.isBannerEmpty = true;
}
}
diff --git a/packages/frontend/core/src/modules/peek-view/view/image-preview/index.tsx b/packages/frontend/core/src/modules/peek-view/view/image-preview/index.tsx
index d97f32328d..8a7c6959e8 100644
--- a/packages/frontend/core/src/modules/peek-view/view/image-preview/index.tsx
+++ b/packages/frontend/core/src/modules/peek-view/view/image-preview/index.tsx
@@ -419,14 +419,18 @@ const ImagePreviewModalImpl = ({
icon={}
onClick={copyHandler}
/>
-
- }
- disabled={blocks.length === 0}
- onClick={() => deleteHandler(cursor)}
- />
+ {blockModel && !blockModel.doc.readonly && (
+ <>
+
+ }
+ disabled={blocks.length === 0}
+ onClick={() => deleteHandler(cursor)}
+ />
+ >
+ )}
diff --git a/packages/frontend/core/src/pages/share/share-detail-page.tsx b/packages/frontend/core/src/pages/share/share-detail-page.tsx
index 33aa80eaf7..c9bd0fd1e2 100644
--- a/packages/frontend/core/src/pages/share/share-detail-page.tsx
+++ b/packages/frontend/core/src/pages/share/share-detail-page.tsx
@@ -33,6 +33,7 @@ import { AppContainer } from '../../components/affine/app-container';
import { PageDetailEditor } from '../../components/page-detail-editor';
import { SharePageNotFoundError } from '../../components/share-page-not-found-error';
import { MainContainer } from '../../components/workspace';
+import { PeekViewManagerModal } from '../../modules/peek-view';
import { CloudBlobStorage } from '../../modules/workspace-engine/impls/engine/blob-cloud';
import * as styles from './share-detail-page.css';
import { ShareFooter } from './share-footer';
@@ -253,6 +254,7 @@ export const Component = () => {
+
diff --git a/tests/affine-cloud/e2e/collaboration.spec.ts b/tests/affine-cloud/e2e/collaboration.spec.ts
index a1adb7f23f..d9b355ef00 100644
--- a/tests/affine-cloud/e2e/collaboration.spec.ts
+++ b/tests/affine-cloud/e2e/collaboration.spec.ts
@@ -5,10 +5,8 @@ import {
addUserToWorkspace,
createRandomUser,
enableCloudWorkspace,
- enableCloudWorkspaceFromShareButton,
loginUser,
} from '@affine-test/kit/utils/cloud';
-import { clickEdgelessModeButton } from '@affine-test/kit/utils/editor';
import {
clickNewPageButton,
getBlockSuiteEditorTitle,
@@ -37,89 +35,6 @@ test.beforeEach(async ({ page }) => {
await loginUser(page, user.email);
});
-test('can enable share page', async ({ page, browser }) => {
- await page.reload();
- await waitForEditorLoad(page);
- await createLocalWorkspace(
- {
- name: 'test',
- },
- page
- );
- await enableCloudWorkspaceFromShareButton(page);
- const title = getBlockSuiteEditorTitle(page);
- await title.pressSequentially('TEST TITLE', {
- delay: 50,
- });
- await page.keyboard.press('Enter', { delay: 50 });
- await page.keyboard.type('TEST CONTENT', { delay: 50 });
- await page.getByTestId('cloud-share-menu-button').click();
- await page.getByTestId('share-menu-create-link-button').click();
- await page.getByTestId('share-menu-copy-link-button').click();
-
- // check share page is accessible
- {
- const context = await browser.newContext();
- await skipOnboarding(context);
- const url: string = await page.evaluate(() =>
- navigator.clipboard.readText()
- );
- const page2 = await context.newPage();
- await page2.goto(url);
- await waitForEditorLoad(page2);
- const title = getBlockSuiteEditorTitle(page2);
- await expect(title).toContainText('TEST TITLE');
- expect(page2.locator('affine-paragraph').first()).toContainText(
- 'TEST CONTENT'
- );
- }
-});
-
-test('share page with default edgeless', async ({ page, browser }) => {
- await page.reload();
- await waitForEditorLoad(page);
- await createLocalWorkspace(
- {
- name: 'test',
- },
- page
- );
- await enableCloudWorkspaceFromShareButton(page);
- const title = getBlockSuiteEditorTitle(page);
- await title.pressSequentially('TEST TITLE', {
- delay: 50,
- });
- await page.keyboard.press('Enter', { delay: 50 });
- await page.keyboard.type('TEST CONTENT', { delay: 50 });
- await clickEdgelessModeButton(page);
- await expect(page.locator('affine-edgeless-root')).toBeVisible({
- timeout: 1000,
- });
- await page.getByTestId('cloud-share-menu-button').click();
- await page.getByTestId('share-menu-create-link-button').click();
- await page.getByTestId('share-menu-copy-link-button').click();
-
- // check share page is accessible
- {
- const context = await browser.newContext();
- await skipOnboarding(context);
- const url: string = await page.evaluate(() =>
- navigator.clipboard.readText()
- );
- const page2 = await context.newPage();
- await page2.goto(url);
- await waitForEditorLoad(page2);
- await expect(page.locator('affine-edgeless-root')).toBeVisible({
- timeout: 1000,
- });
- expect(page2.locator('affine-paragraph').first()).toContainText(
- 'TEST CONTENT'
- );
- const editButton = page2.getByTestId('share-page-edit-button');
- await expect(editButton).not.toBeVisible();
- }
-});
-
// SKIP until BS-671 fix
test.skip('can collaborate with other user and name should display when editing', async ({
page,
diff --git a/tests/affine-cloud/e2e/share-page.spec.ts b/tests/affine-cloud/e2e/share-page.spec.ts
new file mode 100644
index 0000000000..ed56b40adb
--- /dev/null
+++ b/tests/affine-cloud/e2e/share-page.spec.ts
@@ -0,0 +1,151 @@
+import { skipOnboarding, test } from '@affine-test/kit/playwright';
+import {
+ createRandomUser,
+ enableCloudWorkspaceFromShareButton,
+ loginUser,
+} from '@affine-test/kit/utils/cloud';
+import { clickEdgelessModeButton } from '@affine-test/kit/utils/editor';
+import { importImage } from '@affine-test/kit/utils/image';
+import {
+ getBlockSuiteEditorTitle,
+ waitForEditorLoad,
+} from '@affine-test/kit/utils/page-logic';
+import { createLocalWorkspace } from '@affine-test/kit/utils/workspace';
+import { expect } from '@playwright/test';
+
+let user: {
+ id: string;
+ name: string;
+ email: string;
+ password: string;
+};
+
+test.beforeEach(async () => {
+ user = await createRandomUser();
+});
+
+test.beforeEach(async ({ page }) => {
+ await loginUser(page, user.email);
+});
+
+test('can enable share page', async ({ page, browser }) => {
+ await page.reload();
+ await waitForEditorLoad(page);
+ await createLocalWorkspace(
+ {
+ name: 'test',
+ },
+ page
+ );
+ await enableCloudWorkspaceFromShareButton(page);
+ const title = getBlockSuiteEditorTitle(page);
+ await title.pressSequentially('TEST TITLE', {
+ delay: 50,
+ });
+ await page.keyboard.press('Enter', { delay: 50 });
+ await page.keyboard.type('TEST CONTENT', { delay: 50 });
+ await page.getByTestId('cloud-share-menu-button').click();
+ await page.getByTestId('share-menu-create-link-button').click();
+ await page.getByTestId('share-menu-copy-link-button').click();
+
+ // check share page is accessible
+ {
+ const context = await browser.newContext();
+ await skipOnboarding(context);
+ const url: string = await page.evaluate(() =>
+ navigator.clipboard.readText()
+ );
+ const page2 = await context.newPage();
+ await page2.goto(url);
+ await waitForEditorLoad(page2);
+ const title = getBlockSuiteEditorTitle(page2);
+ await expect(title).toContainText('TEST TITLE');
+ expect(page2.locator('affine-paragraph').first()).toContainText(
+ 'TEST CONTENT'
+ );
+ }
+});
+
+test('share page with default edgeless', async ({ page, browser }) => {
+ await page.reload();
+ await waitForEditorLoad(page);
+ await createLocalWorkspace(
+ {
+ name: 'test',
+ },
+ page
+ );
+ await enableCloudWorkspaceFromShareButton(page);
+ const title = getBlockSuiteEditorTitle(page);
+ await title.pressSequentially('TEST TITLE', {
+ delay: 50,
+ });
+ await page.keyboard.press('Enter', { delay: 50 });
+ await page.keyboard.type('TEST CONTENT', { delay: 50 });
+ await clickEdgelessModeButton(page);
+ await expect(page.locator('affine-edgeless-root')).toBeVisible({
+ timeout: 1000,
+ });
+ await page.getByTestId('cloud-share-menu-button').click();
+ await page.getByTestId('share-menu-create-link-button').click();
+ await page.getByTestId('share-menu-copy-link-button').click();
+
+ // check share page is accessible
+ {
+ const context = await browser.newContext();
+ await skipOnboarding(context);
+ const url: string = await page.evaluate(() =>
+ navigator.clipboard.readText()
+ );
+ const page2 = await context.newPage();
+ await page2.goto(url);
+ await waitForEditorLoad(page2);
+ await expect(page.locator('affine-edgeless-root')).toBeVisible({
+ timeout: 1000,
+ });
+ expect(page2.locator('affine-paragraph').first()).toContainText(
+ 'TEST CONTENT'
+ );
+ const editButton = page2.getByTestId('share-page-edit-button');
+ await expect(editButton).not.toBeVisible();
+ }
+});
+
+test('image preview should should be shown', async ({ page, browser }) => {
+ await page.reload();
+ await waitForEditorLoad(page);
+ await createLocalWorkspace(
+ {
+ name: 'test',
+ },
+ page
+ );
+ await enableCloudWorkspaceFromShareButton(page);
+ const title = getBlockSuiteEditorTitle(page);
+ await title.click();
+ await page.keyboard.press('Enter');
+ await importImage(page, 'http://localhost:8081/large-image.png');
+
+ await page.getByTestId('cloud-share-menu-button').click();
+ await page.getByTestId('share-menu-create-link-button').click();
+ await page.getByTestId('share-menu-copy-link-button').click();
+
+ // check share page is accessible
+ {
+ const context = await browser.newContext();
+ await skipOnboarding(context);
+ const url: string = await page.evaluate(() =>
+ navigator.clipboard.readText()
+ );
+ const page2 = await context.newPage();
+ await page2.goto(url);
+ await waitForEditorLoad(page2);
+
+ await page.locator('affine-page-image').first().dblclick();
+ const locator = page.getByTestId('image-preview-modal');
+ await expect(locator).toBeVisible();
+ await page.getByTestId('image-preview-close-button').first().click();
+ await page.waitForTimeout(500);
+ await expect(locator).not.toBeVisible();
+ }
+});
diff --git a/tests/affine-cloud/playwright.config.ts b/tests/affine-cloud/playwright.config.ts
index 75c1775e2f..ed072898d8 100644
--- a/tests/affine-cloud/playwright.config.ts
+++ b/tests/affine-cloud/playwright.config.ts
@@ -10,7 +10,7 @@ const config: PlaywrightTestConfig = {
timeout: 120_000,
outputDir: testResultDir,
use: {
- baseURL: 'http://localhost:8081/',
+ baseURL: 'http://localhost:8080/',
browserName:
(process.env.BROWSER as PlaywrightWorkerOptions['browserName']) ??
'chromium',
@@ -26,6 +26,16 @@ const config: PlaywrightTestConfig = {
retries: 1,
reporter: process.env.CI ? 'github' : 'list',
webServer: [
+ {
+ command: 'yarn run serve:test-static',
+ port: 8081,
+ timeout: 120 * 1000,
+ reuseExistingServer: !process.env.CI,
+ env: {
+ COVERAGE: process.env.COVERAGE || 'false',
+ ENABLE_DEBUG_PAGE: '1',
+ },
+ },
// Intentionally not building the web, reminds you to run it by yourself.
{
command: 'yarn -T run start:web-static',
diff --git a/tests/affine-local/e2e/image-preview.spec.ts b/tests/affine-local/e2e/image-preview.spec.ts
index 8448cb6f7b..4a4bcb333a 100644
--- a/tests/affine-local/e2e/image-preview.spec.ts
+++ b/tests/affine-local/e2e/image-preview.spec.ts
@@ -2,41 +2,16 @@
import fs from 'node:fs';
import { test } from '@affine-test/kit/playwright';
+import { importImage } from '@affine-test/kit/utils/image';
import { openHomePage } from '@affine-test/kit/utils/load-page';
import {
clickNewPageButton,
- focusInlineEditor,
getBlockSuiteEditorTitle,
waitForEditorLoad,
} from '@affine-test/kit/utils/page-logic';
import type { Page } from '@playwright/test';
import { expect } from '@playwright/test';
-async function importImage(page: Page, url: string) {
- await focusInlineEditor(page);
- await page.evaluate(
- ([url]) => {
- const clipData = {
- 'text/html': `
`,
- };
- const e = new ClipboardEvent('paste', {
- clipboardData: new DataTransfer(),
- });
- Object.defineProperty(e, 'target', {
- writable: false,
- value: document,
- });
- Object.entries(clipData).forEach(([key, value]) => {
- e.clipboardData?.setData(key, value);
- });
- document.dispatchEvent(e);
- },
- [url]
- );
- // TODO(@catsjuice): wait for image to be loaded more reliably
- await page.waitForTimeout(1000);
-}
-
async function closeImagePreviewModal(page: Page) {
await page.getByTestId('image-preview-close-button').first().click();
await page.waitForTimeout(500);
diff --git a/tests/kit/utils/image.ts b/tests/kit/utils/image.ts
new file mode 100644
index 0000000000..931f603849
--- /dev/null
+++ b/tests/kit/utils/image.ts
@@ -0,0 +1,28 @@
+import type { Page } from '@playwright/test';
+
+import { focusInlineEditor } from './page-logic';
+
+export async function importImage(page: Page, url: string) {
+ await focusInlineEditor(page);
+ await page.evaluate(
+ ([url]) => {
+ const clipData = {
+ 'text/html': `
`,
+ };
+ const e = new ClipboardEvent('paste', {
+ clipboardData: new DataTransfer(),
+ });
+ Object.defineProperty(e, 'target', {
+ writable: false,
+ value: document,
+ });
+ Object.entries(clipData).forEach(([key, value]) => {
+ e.clipboardData?.setData(key, value);
+ });
+ document.dispatchEvent(e);
+ },
+ [url]
+ );
+ // TODO(@catsjuice): wait for image to be loaded more reliably
+ await page.waitForTimeout(1000);
+}