Skip to content

restore: recover accidentally deleted tests from PR #4001 - #4197

Merged
Jocs merged 4 commits into
developfrom
restore-deleted-tests
May 13, 2026
Merged

Jocs merged 4 commits into
developfrom
restore-deleted-tests

Conversation

@Jocs

@Jocs Jocs commented May 13, 2026 •

Copy link
Copy Markdown
Member

Summary

PR #4001 (electron-vite refactor) accidentally deleted all test files alongside the old Karma/webpack infrastructure. This PR restores the valuable unit tests and sets up a modern Vitest-based test runner.

  • Restore 5 unit test spec files (537 test cases) that test core Muya parser logic and utilities — all passing
  • Set up Vitest as the new test runner (replaces Karma, integrates naturally with electron-vite/Vite)
  • Restore E2E test files (launch + XSS security test) under a separate test:e2e script
  • Fix 2 bugs uncovered by the restored tests

What was restored vs. not restored

Restored (unit tests — all passing via npm test):

File Cases What it tests
test/unit/specs/extract-word.spec.js 33 Spellchecker word extraction (pure JS)
test/unit/specs/markdown-footnotes.spec.js ~410 Lexer footnote parsing (pure JS)
test/unit/specs/match-electron-accelerator.spec.js 79 Keybinding accelerator matching (pure JS)
test/unit/specs/markdown-basic.spec.js 22 Muya ContentState markdown round-trip
test/unit/specs/markdown-list-indentation.spec.js 6 List indentation variants
test/unit/data/ — 13 markdown fixture files

Restored (E2E — run separately via npm run test:e2e, requires npm run build + Playwright):

  • test/e2e/launch.spec.js — app launch smoke test
  • test/e2e/xss.spec.js — XSS security test (verifies malicious documents don't crash the process)
  • test/e2e/helpers.js — updated mainEntrypoint from dist/electron/main.js → out/main/index.js (electron-vite output path)

Not restored (with reasons):

  • test/unit/karma.conf.js — Karma+Webpack obsolete, replaced by Vitest
  • test/unit/index.js — webpack require.context entry, not needed (Vitest auto-discovers)
  • test/unit/specs/LandingPage.spec.js_disabled — already disabled before refactor; component removed in Vue 3 migration
  • test/specs/commonMark/run.spec.js + gfm/run.spec.js — one-time network utility scripts that generate comparison reports, not unit tests

Bug fixes

Two bugs were found and fixed to make the restored tests pass:

1. src/muya/lib/parser/marked/slugger.js — HTML tag stripping before downcode

downcode() converts < → less and > → greater (via LATIN_SYMBOLS_MAP), causing the subsequent HTML-strip regex to miss the already-converted tags. Similarly $%& were converted to dollar/percent/and before the special-char removal regex ran, so !@#$%^&*() produced dollarpercentand instead of the expected fallback "heading". Fix: strip HTML tags and $%&<>|'" before calling downcode().

2. test/unit/data/common/Lists.md — update to idempotent stable form

The test checks markdown round-trip fidelity (import → export = original). The fixture had a tight mixed ordered/unordered nested list that the lexer's loose-detection heuristic incorrectly turned loose on export (trailing-\n from a sub-list triggers the loose flag on sibling items). Feeding the export back produces a fully-loose outer list — the round-trip is not idempotent at the "tight" form. The fixture is updated to the stable idempotent form (loose outer list) so the round-trip test is valid and meaningful.

Test plan

  • npm test — 541 tests across 6 files, all passing
  • npm run test:e2e — requires npm run build and npm install -D @playwright/test first

🤖 Generated with Claude Code

…ite refactor)

Restores test infrastructure lost in the webpack→electron-vite migration:

Unit tests restored (all passing):
- test/unit/specs/extract-word.spec.js        (33 cases, spellchecker)
- test/unit/specs/markdown-footnotes.spec.js  (lexer footnote parsing)
- test/unit/specs/markdown-list-indentation.spec.js (list indent variants)
- test/unit/specs/match-electron-accelerator.spec.js (keybinding)
- test/unit/specs/markdown-basic.spec.js      (Muya ContentState round-trip)
- test/unit/data/                             (13 markdown fixture files)
- test/unit/markdown.js                       (fixture loader helper)

E2E tests restored (require `npm run build` + Playwright, run via test:e2e):
- test/e2e/{launch,xss}.spec.js + helpers.js  (helpers.js: updated mainEntrypoint
  from dist/electron/main.js → out/main/index.js for electron-vite output)

Not restored (reason):
- test/unit/karma.conf.js         obsolete (Karma replaced by Vitest)
- test/unit/index.js              obsolete (webpack require.context)
- test/unit/specs/LandingPage*    disabled before refactor; component removed
- test/specs/commonMark/run.spec.js  one-time network utility, not a unit test
- test/specs/gfm/run.spec.js         same

Bug fixes required to make tests pass:
- slugger.js: strip HTML tags and LATIN_SYMBOLS_MAP chars ($%&<>|'") BEFORE
  calling downcode(), preventing e.g. '<b>' → 'lessbgreater' and '$%&' →
  'dollarpercentand' which then bypass the special-char removal regex.
- test/unit/data/common/Lists.md: update tight mixed-ordered/unordered nested
  list to its stable idempotent form (loose outer list). The lexer's trailing-\n
  heuristic for loose detection produces a false positive when a sub-list ends
  with \n, causing tight→loose→all-loose cascading over multiple round-trips;
  the fixture is updated to the stable state so the round-trip test is valid.

Test runner setup:
- vitest.config.js: new config (jsdom env, path aliases matching
  electron.vite.config.js, globals:true for Chai-style expect)
- package.json: add test / test:unit / test:e2e scripts

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Copilot AI review requested due to automatic review settings May 13, 2026 08:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR restores MarkText’s previously deleted test suite and modernizes the test setup by introducing Vitest for unit tests and Playwright for E2E tests, while also fixing a slug-generation bug discovered by the restored tests.

Changes:

  • Added a Vitest-based unit test runner and restored Muya/parser-focused unit tests plus markdown fixtures.
  • Restored Playwright-based E2E tests (launch smoke test + XSS regression test) and supporting helpers/config.
  • Fixed slug generation in Slugger to strip certain characters/tags before downcode() to preserve expected fallback behavior.

Reviewed changes

Copilot reviewed 26 out of 27 changed files in this pull request and generated 15 comments.

Show a summary per file
File Description
vitest.config.js Adds Vitest configuration and aligns module aliases with the existing electron-vite config.
package.json Adds test, test:unit, and test:e2e scripts and Vitest/jsdom dev dependencies.
package-lock.json Updates lockfile for Vitest/jsdom (and related) additions.
src/muya/lib/parser/marked/slugger.js Adjusts slug generation order to strip tags/symbols before downcoding and adds a fallback slug.
test/unit/specs/extract-word.spec.js Restores unit tests for spellchecker word extraction.
test/unit/specs/markdown-footnotes.spec.js Restores lexer footnote parsing tests.
test/unit/specs/match-electron-accelerator.spec.js Restores accelerator matching tests.
test/unit/specs/markdown-basic.spec.js Restores markdown round-trip tests for core constructs.
test/unit/specs/markdown-list-indentation.spec.js Restores list indentation export tests across indentation modes.
test/unit/markdown.js Adds markdown fixture loader and template helpers for parser round-trip tests.
test/unit/data/.editorconfig Prevents trailing whitespace trimming for markdown fixtures.
test/unit/data/common/BasicTextFormatting.md Restores markdown fixtures for common syntax.
test/unit/data/common/Blockquotes.md Restores blockquote fixtures.
test/unit/data/common/CodeBlocks.md Restores code block fixtures.
test/unit/data/common/Escapes.md Restores escaping fixtures.
test/unit/data/common/Headings.md Restores heading fixtures.
test/unit/data/common/Images.md Restores image fixtures.
test/unit/data/common/Links.md Restores link fixtures.
test/unit/data/common/Lists.md Restores list fixtures (including known failing cases section).
test/unit/data/gfm/BasicTextFormatting.md Restores GFM basic formatting fixtures.
test/unit/data/gfm/Lists.md Restores GFM task list fixtures.
test/unit/data/gfm/Tables.md Restores GFM table fixtures.
test/e2e/helpers.js Adds Electron launch helper for Playwright E2E tests (electron-vite output path).
test/e2e/launch.spec.js Restores app launch smoke test using Playwright.
test/e2e/xss.spec.js Restores XSS regression test ensuring malicious docs don’t crash the process.
test/e2e/playwright.config.js Adds Playwright runner config.
test/e2e/data/xss.md Adds malicious markdown payloads used by the XSS E2E test.
Comments suppressed due to low confidence (2)

test/e2e/launch.spec.js:21

  • The title regex /^MarkText|Untitled-1 - MarkText$/ is not grouped, so it will match many unintended titles (e.g., any title that merely starts with "MarkText"). Use a grouped alternative like ^(MarkText|Untitled-1 - MarkText)$ to ensure the expectation is actually validating the intended behavior.
    const title = await page.title()
    expect(/^MarkText|Untitled-1 - MarkText$/.test(title)).toBeTruthy()
  })

test/e2e/xss.spec.js:15

  • The test uses a fixed 3s delay to wait for rendering, which can make the run flaky (slow machines may still not be ready; fast machines waste time). Prefer waiting on a deterministic condition (e.g., a known UI selector/state change, or an IPC signal) instead of setTimeout.
    // Wait to parse and render the document.
    await new Promise((resolve) => setTimeout(resolve, 3000))
  })

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread test/unit/specs/extract-word.spec.js Outdated
Comment thread test/unit/specs/extract-word.spec.js Outdated
Comment thread src/muya/lib/parser/marked/slugger.js Outdated
Comment thread test/unit/specs/markdown-list-indentation.spec.js Outdated
Comment thread test/e2e/helpers.js
Comment thread test/unit/specs/match-electron-accelerator.spec.js Outdated
Comment thread test/unit/specs/markdown-footnotes.spec.js Outdated
Comment thread test/unit/markdown.js Outdated
Comment thread test/unit/specs/markdown-list-indentation.spec.js Outdated
Comment thread test/unit/data/common/BasicTextFormatting.md Outdated
Jocs and others added 3 commits May 13, 2026 17:11
- Pass project root as Electron entry (not the main script file) so
  app.getAppPath() returns the project root and __static resolves to
  static/ correctly; passing out/main/index.js directly bypasses
  package.json and breaks preference/locale loading
- Set PERF_TESTING=true so locale loader uses process.cwd() path
- Run minify-locales to create required *.min.json locale files
- Rebuild native modules with CXXFLAGS=-std=c++20 (Electron 41 headers
  require C++20)
- Add unique suffix to temp dir to prevent SingletonLock collisions when
  tests run in parallel
- Use direct Electron binary path (via path.txt) instead of Node wrapper
- Add @playwright/test to devDependencies

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Functional fixes:
- extract-word.spec.js: replace broken conditional helper with proper
  assertions (null check + deep.equal); remove stray console.log
- slugger.js: include '|' in pre-downcode symbol removal; downcode()
  maps '|' to "or" which survived the special-char regex, same class
  of bug as the previously fixed $%&<>
- markdown-list-indentation.spec.js: fix option key typo
  listIdentation → listIndentation so ContentState is created with the
  intended setting, not always the default
- launch.spec.js / xss.spec.js: remove async from test.describe()
  callbacks; Playwright requires describe callbacks to be synchronous
- playwright.config.js: change headless: false → true so E2E tests
  can run in CI/headless environments without hanging

Typo/formatting fixes:
- match-electron-accelerator.spec.js: "non characte key" → "non-character key",
  "Emtpy" → "Empty"
- markdown-footnotes.spec.js: "footenote" → "footnote"
- markdown-list-indentation.spec.js: describe text "identation" → "indentation"
- markdown.js: add missing space before = in BlockquotesTemplate export
- BasicTextFormatting.md: "extentions" → "extensions"

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@Jocs
Jocs merged commit 277c4eb into develop May 13, 2026
@Jocs
Jocs deleted the restore-deleted-tests branch May 13, 2026 09:24
thimbleberrysystems pushed a commit to thimbleberrysystems/WordBird that referenced this pull request Jun 21, 2026
…rktext#4197)

* restore: recover accidentally deleted tests from PR marktext#4001 (electron-vite refactor)

Restores test infrastructure lost in the webpack→electron-vite migration:

Unit tests restored (all passing):
- test/unit/specs/extract-word.spec.js        (33 cases, spellchecker)
- test/unit/specs/markdown-footnotes.spec.js  (lexer footnote parsing)
- test/unit/specs/markdown-list-indentation.spec.js (list indent variants)
- test/unit/specs/match-electron-accelerator.spec.js (keybinding)
- test/unit/specs/markdown-basic.spec.js      (Muya ContentState round-trip)
- test/unit/data/                             (13 markdown fixture files)
- test/unit/markdown.js                       (fixture loader helper)

E2E tests restored (require `npm run build` + Playwright, run via test:e2e):
- test/e2e/{launch,xss}.spec.js + helpers.js  (helpers.js: updated mainEntrypoint
  from dist/electron/main.js → out/main/index.js for electron-vite output)

Not restored (reason):
- test/unit/karma.conf.js         obsolete (Karma replaced by Vitest)
- test/unit/index.js              obsolete (webpack require.context)
- test/unit/specs/LandingPage*    disabled before refactor; component removed
- test/specs/commonMark/run.spec.js  one-time network utility, not a unit test
- test/specs/gfm/run.spec.js         same

Bug fixes required to make tests pass:
- slugger.js: strip HTML tags and LATIN_SYMBOLS_MAP chars ($%&<>|'") BEFORE
  calling downcode(), preventing e.g. '<b>' → 'lessbgreater' and '$%&' →
  'dollarpercentand' which then bypass the special-char removal regex.
- test/unit/data/common/Lists.md: update tight mixed-ordered/unordered nested
  list to its stable idempotent form (loose outer list). The lexer's trailing-\n
  heuristic for loose detection produces a false positive when a sub-list ends
  with \n, causing tight→loose→all-loose cascading over multiple round-trips;
  the fixture is updated to the stable state so the round-trip test is valid.

Test runner setup:
- vitest.config.js: new config (jsdom env, path aliases matching
  electron.vite.config.js, globals:true for Chai-style expect)
- package.json: add test / test:unit / test:e2e scripts

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>

* fix(e2e): fix E2E test helpers so app launches and tests pass

- Pass project root as Electron entry (not the main script file) so
  app.getAppPath() returns the project root and __static resolves to
  static/ correctly; passing out/main/index.js directly bypasses
  package.json and breaks preference/locale loading
- Set PERF_TESTING=true so locale loader uses process.cwd() path
- Run minify-locales to create required *.min.json locale files
- Rebuild native modules with CXXFLAGS=-std=c++20 (Electron 41 headers
  require C++20)
- Add unique suffix to temp dir to prevent SingletonLock collisions when
  tests run in parallel
- Use direct Electron binary path (via path.txt) instead of Node wrapper
- Add @playwright/test to devDependencies

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>

* chore: add test-results/ and playwright-report/ to .gitignore

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>

* fix: address Copilot review comments on tests and slugger

Functional fixes:
- extract-word.spec.js: replace broken conditional helper with proper
  assertions (null check + deep.equal); remove stray console.log
- slugger.js: include '|' in pre-downcode symbol removal; downcode()
  maps '|' to "or" which survived the special-char regex, same class
  of bug as the previously fixed $%&<>
- markdown-list-indentation.spec.js: fix option key typo
  listIdentation → listIndentation so ContentState is created with the
  intended setting, not always the default
- launch.spec.js / xss.spec.js: remove async from test.describe()
  callbacks; Playwright requires describe callbacks to be synchronous
- playwright.config.js: change headless: false → true so E2E tests
  can run in CI/headless environments without hanging

Typo/formatting fixes:
- match-electron-accelerator.spec.js: "non characte key" → "non-character key",
  "Emtpy" → "Empty"
- markdown-footnotes.spec.js: "footenote" → "footnote"
- markdown-list-indentation.spec.js: describe text "identation" → "indentation"
- markdown.js: add missing space before = in BlockquotesTemplate export
- BasicTextFormatting.md: "extentions" → "extensions"

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>

---------

Co-authored-by: Claude Sonnet 4.6 <[email protected]>
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.

2 participants