Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ and this project adheres to

### Fixed

- 🐛(frontend) save edits made while the http fallback carries the document
- ✅(e2e) find comment menus in their portal and accept the Typst PDF language
- ✅(e2e) skip the version dialog tests, replaced by the BlockNote sidebar
- 🐛(frontend) fetch named versions fresh after deleting one
- 🐛(documentation) fix minio port and keycloak realm in the k8s guide #2751
- 🐛(collaboration) bound the calls yhub makes to the backend with a timeout,
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ test.describe('Doc Comments', () => {
// Edit Comment
await thread.getByText('This is a comment').first().hover();
await thread.locator('[data-test="moreactions"]').first().click();
await thread.getByRole('menuitem', { name: 'Edit comment' }).click();
await page.getByRole('menuitem', { name: 'Edit comment' }).click();
const commentEditor = thread.getByText('This is a comment').first();
await commentEditor.fill('This is an edited comment');
const saveBtn = thread.locator('button[data-test="save"]').first();
Expand All @@ -187,7 +187,7 @@ test.describe('Doc Comments', () => {
// Delete second comment
await thread.getByText('This is a second comment').first().hover();
await thread.locator('[data-test="moreactions"]').first().click();
await thread.getByRole('menuitem', { name: 'Delete comment' }).click();
await page.getByRole('menuitem', { name: 'Delete comment' }).click();
await expect(
thread.getByText('This is a second comment').first(),
).toBeHidden();
Expand Down Expand Up @@ -240,7 +240,7 @@ test.describe('Doc Comments', () => {

await thread.getByText('This is a new comment').first().hover();
await thread.locator('[data-test="moreactions"]').first().click();
await thread.getByRole('menuitem', { name: 'Delete comment' }).click();
await page.getByRole('menuitem', { name: 'Delete comment' }).click();

await expect(editor.getByText('Hello')).not.toHaveClass('bn-thread-mark');
await expect(editor.getByText('Hello')).toHaveCSS(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,8 @@ test.describe('Doc Export', () => {
const pdfBuffer = await cs.toBuffer(await download.createReadStream());
const pdfString = pdfBuffer.toString('latin1');

expect(pdfString).toContain('/Lang (fr)');
// Typst writes `/Lang(fr)`, other PDF writers `/Lang (fr)`.
expect(pdfString).toMatch(/\/Lang\s*\(fr\)/);
});

test('it exports the doc to PDF with PRINT feature and checks regressions', async ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ import { openSuggestionMenu, writeInEditor } from './utils-editor';
const COLLABORATION_VERSION_GRANULARITY_MS = 2000;

test.describe('Doc Version', () => {
test('it displays the doc versions', async ({ page, browserName }) => {
// The BlockNote version history sidebar replaced the "Version history" dialog that
// these tests use, and the history groups edits by at least 5 minutes.
test.skip('it displays the doc versions', async ({ page, browserName }) => {
await overrideConfig(page, {
COLLABORATION_VERSION_GRANULARITY_MS: `${COLLABORATION_VERSION_GRANULARITY_MS}`,
});
Expand Down Expand Up @@ -113,7 +115,9 @@ test.describe('Doc Version', () => {
await expect(page.getByRole('menuitem', { name: 'History' })).toBeHidden();
});

test('it restores the doc version', async ({ page, browserName }) => {
// The BlockNote version history sidebar replaced the "Version history" dialog that
// these tests use, and the history groups edits by at least 5 minutes.
test.skip('it restores the doc version', async ({ page, browserName }) => {
await overrideConfig(page, {
COLLABORATION_VERSION_GRANULARITY_MS: `${COLLABORATION_VERSION_GRANULARITY_MS}`,
});
Expand Down
11 changes: 11 additions & 0 deletions src/frontend/apps/e2e/__tests__/app-impress/utils-export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,17 @@ export const comparePDFWithAssetFolder = async ({
const referencePdfPath = path.join(__dirname, 'assets', filename);
const referencePdfBuffer = fs.readFileSync(referencePdfPath);

// The generated PDF, in the report: the new fixture when a change is intended.
if (testInfo) {
await writeReport(
testInfo,
filename,
'generated-pdf',
originPdfBuffer,
'application/pdf',
);
}

// Parse both PDFs
const generatedPdf = new PDFParse({ data: originPdfBuffer });
const referencePdf = new PDFParse({ data: referencePdfBuffer });
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Awareness } from '@y/protocols/awareness';
import * as Y from '@y/y';
import { encodeAny } from 'lib0/buffer';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';

import { useProviderStore } from '../useProviderStore';
Expand Down Expand Up @@ -180,6 +181,25 @@ describe('useProviderStore', () => {
expect(useProviderStore.getState().isReady).toBe(true);
});

it('reports the websocket provider as synced once the http fallback syncs', async () => {
// The socket never connects; the editor binds only to a synced provider.
vi.stubGlobal(
'fetch',
vi.fn(
async () =>
new Response(
new Uint8Array(
encodeAny({ doc: Y.encodeStateAsUpdate(new Y.Doc()) }),
),
),
),
);
// The fallback starts 5s after the socket fails, then polls once.
await vi.advanceTimersByTimeAsync(6000);
expect(provider.synced).toBe(true);
expect(useProviderStore.getState().isSynced).toBe(true);
});

it('tears everything down with the document', () => {
useProviderStore.getState().destroyProvider();
expect(provider.destroy).toHaveBeenCalled();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,13 @@ export const useCollaborationStore = create<UseCollaborationStore>()(
doc,
`${target.serverUrl}/ydoc/v1/${target.org}/${storeId}?branch=main&gc=true&awareness=${!readOnly}`,
readOnly ? undefined : awareness,
() => set({ isSynced: true, isReady: true }),
() => {
// BlockNote binds the editor to the doc once the provider reports
// `synced`. The socket never syncs while it is blocked, so without
// this the editor accepts text that never reaches the doc.
provider.synced = true;
set({ isSynced: true, isReady: true });
},
() => {
provider.shouldConnect = false;
clearTimeout(fallbackTimeout);
Expand Down
Loading