Skip to content

Conversation

@Yinlin124
Copy link

@Yinlin124 Yinlin124 commented Sep 9, 2025

PR

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • Other... Please describe:
    • 新增协同编辑冲突编辑用例、多浏览器测试

Summary by CodeRabbit

  • Tests

    • Expanded cross-browser coverage for the collaborative editor demo, running suites in Chromium and WebKit.
    • Improved reliability with per-browser isolation, enhanced cleanup, and concurrent edit-conflict validation.
    • Strengthened in-browser checks for formatting, headings, font size, links, and other rich-text features.
  • Chores

    • Test orchestration refactored for clearer setup/teardown and faster parallel execution.
    • No user-facing changes; functionality remains the same.

@coderabbitai
Copy link

coderabbitai bot commented Sep 9, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Pre-merge checks (2 passed, 1 warning)

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title “test: 新增协同编辑冲突编辑用例、多浏览器测试” directly and clearly summarizes the primary additions of collaborative editing conflict test cases and multi-browser testing support without extraneous detail or ambiguity. It is concise, specific to the test suite changes, and will help teammates quickly understand the main purpose of this pull request.
✨ Finishing touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@vaebe
Copy link
Contributor

vaebe commented Sep 10, 2025

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Sep 10, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/docs/fluent-editor/demos/collaborative-editing.spec.ts (1)

12-28: Add error handling for browser launch failures.

The function should handle potential browser launch failures more gracefully to provide better debugging information when tests fail.

 async function openTwoPages(browserType = chromium): Promise<[Page, Page, Browser, Browser]> {
-  const browser1 = await browserType.launch()
-  const browser2 = await browserType.launch()
+  let browser1: Browser, browser2: Browser
+  try {
+    browser1 = await browserType.launch()
+    browser2 = await browserType.launch()
+  } catch (error) {
+    throw new Error(`Failed to launch browsers: ${error}`)
+  }

   const page1 = await browser1.newPage()
   const page2 = await browser2.newPage()
🧹 Nitpick comments (5)
packages/docs/fluent-editor/demos/collaborative-editing.spec.ts (5)

1-1: Consider adding Firefox for broader browser coverage.

While Chrome and WebKit provide good coverage, adding Firefox would ensure testing across all major browser engines (Blink, WebKit, and Gecko).

-import { type Browser, chromium, expect, type Page, test, webkit } from '@playwright/test'
+import { type Browser, chromium, firefox, expect, type Page, test, webkit } from '@playwright/test'

And update the browsers array:

 const browsers = [
   { name: 'chromium', launcher: chromium },
   { name: 'webkit', launcher: webkit },
+  { name: 'firefox', launcher: firefox },
 ]

122-149: Complex font size test logic could be simplified.

The nested conditions and string manipulation make this test hard to follow. Consider extracting the validation logic.

+async function validateFontSize(page: Page, size: string, text: string): Promise<boolean> {
+  if (size === '12px') {
+    const hasParagraph = await page.locator(`.ql-editor p:has-text("${text}")`).count()
+    const hasSpan = await page.locator('.ql-editor span[style*="font-size"]').count()
+    return hasParagraph > 0 && hasSpan === 0
+  }
+  return (await page.locator(`.ql-editor span[style*="font-size: ${size}"]`).count()) > 0
+}

 test('size collaborative-editing test', async () => {
   await typeSync(p1, p2, 'HEAD')
   await p1.locator('.ql-editor').click()
   await selectAll(p1)

   const sequence = ['12px', '14px', '14px', '16px', '16px', '18px', '18px', '20px', '20px', '24px', '24px', '32px']

   let current = sequence[0]

   for (let i = 1; i < sequence.length; i++) {
     const next = sequence[i]
     if (next === current) {
       continue
     }
     await p1.getByRole('button', { name: current }).click()
     await p1.getByRole('button', { name: next }).click()

     const sizeMatch = next.match(/\d+px/)
     if (!sizeMatch) continue
     const size = sizeMatch[0]
-    if (size === '12px') {
-      await expect.poll(async () => {
-        const hasParagraph = await p2.locator('.ql-editor p:has-text("HEAD")').count()
-        const hasSpan = await p2.locator('.ql-editor span[style*="font-size"]').count()
-        return hasParagraph > 0 && hasSpan === 0
-      }).toBeTruthy()
-    }
-    else {
-      await expect.poll(async () => (await p2.locator(`.ql-editor span[style*="font-size: ${size}"]`).count()) > 0).toBeTruthy()
-    }
+    await expect.poll(() => validateFontSize(p2, size, 'HEAD')).toBeTruthy()
     current = next
   }
 })

316-323: Consider adding timeout for conflict resolution polling.

The polling for text convergence could potentially hang if the collaborative system fails. Consider adding an explicit timeout.

-      await expect.poll(async () => {
+      await expect.poll(async () => {
         const text1 = await p1.locator('.ql-editor').textContent()
         const text2 = await p2.locator('.ql-editor').textContent()
         if (text1 === text2 && (text1 === 'AB' || text1 === 'BA')) {
           return true
         }
         return false
-      }).toBeTruthy()
+      }, { timeout: 10000 }).toBeTruthy()

172-182: Consider extracting common test patterns.

The format tests follow a very similar pattern. Consider creating a data-driven test to reduce duplication.

+const formatTestCases = [
+  { format: 'bold', tag: 'strong' },
+  { format: 'italic', tag: 'em' },
+  { format: 'underline', tag: 'u' },
+  { format: 'strike', tag: '.ql-custom-strike' }
+]
+
-const formatTypes = ['bold', 'italic', 'underline', 'strike']
-formatTypes.forEach((fmt) => {
-  test(`${fmt} collaborative-editing test`, async () => {
-    await typeSync(p1, p2, fmt)
+formatTestCases.forEach(({ format, tag }) => {
+  test(`${format} collaborative-editing test`, async () => {
+    await typeSync(p1, p2, format)
     await selectAll(p1)
-    await p1.getByLabel(fmt).click()
-    const tagMap: Record<string, string> = { bold: 'strong', italic: 'em', underline: 'u', strike: '.ql-custom-strike' }
-    const tag = tagMap[fmt]
+    await p1.getByLabel(format).click()
     await expect.poll(async () => (await p2.locator(`.ql-editor ${tag}`).count()) > 0).toBeTruthy()
   })
 })

42-326: Consider adding more complex conflict scenarios.

While the basic simultaneous edit test is good, consider adding tests for more complex conflict scenarios such as:

  • Multiple users editing the same line
  • Conflicting format changes
  • Simultaneous list operations

Would you like me to help create additional conflict resolution test cases to cover more complex collaborative editing scenarios?

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c9a8417 and 508ce3f.

📒 Files selected for processing (1)
  • packages/docs/fluent-editor/demos/collaborative-editing.spec.ts (2 hunks)
🔇 Additional comments (3)
packages/docs/fluent-editor/demos/collaborative-editing.spec.ts (3)

91-97: Good helper function for heading verification.

The headingMatched helper properly checks for both standard HTML heading elements and Quill's custom heading classes, making the tests more robust.


256-260: Good defensive check for prompt input visibility.

The check for prompt input visibility before filling it prevents test failures when the UI behavior changes.


307-324: Excellent conflict resolution test implementation.

The simultaneous edit test properly verifies that concurrent edits are handled correctly, accepting either 'AB' or 'BA' as valid outcomes, which correctly tests the conflict resolution behavior of the collaborative editor.

@kagol kagol merged commit 7008890 into opentiny:ospp-2025/collaborative-editing Sep 15, 2025
@Yinlin124 Yinlin124 deleted the test/collab branch September 15, 2025 06:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants