fix(core): can not preview image in shared page (#7466)

FIx BS-798
This commit is contained in:
L-Sun
2024-07-18 06:33:52 +00:00
parent 71ddb1f841
commit 9160469a18
9 changed files with 207 additions and 124 deletions
@@ -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);
}
@@ -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;
}
}
@@ -419,14 +419,18 @@ const ImagePreviewModalImpl = ({
icon={<CopyIcon />}
onClick={copyHandler}
/>
<div className={styles.dividerStyle}></div>
<ButtonWithTooltip
data-testid="delete-button"
tooltip="Delete"
icon={<DeleteIcon />}
disabled={blocks.length === 0}
onClick={() => deleteHandler(cursor)}
/>
{blockModel && !blockModel.doc.readonly && (
<>
<div className={styles.dividerStyle}></div>
<ButtonWithTooltip
data-testid="delete-button"
tooltip="Delete"
icon={<DeleteIcon />}
disabled={blocks.length === 0}
onClick={() => deleteHandler(cursor)}
/>
</>
)}
</div>
</div>
</div>
@@ -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 = () => {
</div>
</div>
</MainContainer>
<PeekViewManagerModal />
</AppContainer>
</FrameworkScope>
</FrameworkScope>
@@ -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,
+151
View File
@@ -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();
}
});
+11 -1
View File
@@ -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',
+1 -26
View File
@@ -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': `<img alt={'Sample image'} src=${url} />`,
};
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);
+28
View File
@@ -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': `<img alt={'Sample image'} src=${url} />`,
};
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);
}