Skip to content

feat: Playwright公式docsをNotebookLM向けに取得・前処理するツールを追加 - #2

Merged
t0k6 merged 9 commits into
mainfrom
feat/playwright-docs-notebooklm-export
Jun 19, 2026
Merged

t0k6 merged 9 commits into
mainfrom
feat/playwright-docs-notebooklm-export

Conversation

@t0k6

@t0k6 t0k6 commented Jun 17, 2026 •

Copy link
Copy Markdown
Owner

概要

Playwright公式 Node.js ドキュメントを NotebookLM / Gemini 向けに取得・前処理・保存する独立ツール playwright-official-docs/ を追加する。既存の E2E エクスポートツールを補完し、公式 MDX ソースからノイズを除去した Markdown を冪等に生成できる。

変更内容

  • playwright-official-docs/ に CLI・設定・取得・前処理・bundle 生成のパイプラインを追加
  • 公式 stable サイドバーと versioned_docs/version-stable/*.mdx から docs ページを取得(API reference は対象外)
  • 出力: pages/、notebooklm/(カテゴリ bundle)、PROJECT_INDEX.md、manifest.json、url-review.md 等
  • MDX 前処理: Docusaurus import / Tabs / JSX コンポーネント除去、languages.mdx の言語絞り込み、API reference フッター削除
  • コードフェンス内の import 行は保持し、MDX 用 import のみ除去
  • パス検証・trusted URL ホスト制限・fixture MDX の containment・原子書き込みなど安全性を強化
  • npm run export:playwright-docs / export:playwright-docs:check スクリプトと fixture ベースのユニット/統合テストを追加
  • ルート README に関連ツールへのリンクを追記

技術的な詳細

  • mock-browser-apis など frontmatter id とファイル名 stem が異なるページは MDX カタログで解決
  • writeAtomically で tmp → rename による冪等出力。失敗時はバックアップから復元
  • gemini-export 共通の resolveWithinRepo / assertWithinRepoRoot を再利用

テスト内容

  • npm test: 151 pass / 1 skip(symlink テストは Windows 環境で skip)
  • npm run lint: エラーなし
  • fixture モードでのエクスポート・冪等性・パス逸脱拒否を統合テストで検証
  • 前処理(Tabs 展開、コードフェンス内 import 保持、languages 絞り込み等)をユニットテストで検証

関連Issue

  • なし

Made with Cursor

Summary by CodeRabbit

リリースノート

  • New Features
    • Playwright公式ドキュメントをNotebookLM/Gemini向けに変換・エクスポートするツール群を追加
    • 変換CLI(--check/--fixture-dir)と、カテゴリ別バンドル・補助ドキュメント(一覧/差分レビュー/インデックス/manifest)生成に対応
    • export:playwright-docs / export:playwright-docs:check を追加し、Node.js 最小要件(>=18)を設定
  • Documentation
    • READMEに「関連ツール」セクションを追加
    • 変換手順と成果物構成を説明する専用READMEを新規追加
  • Chores
    • .gitignore と eslint の対象範囲を更新
  • Tests
    • CLI/E2Eと主要処理(変換・バンドル・設定・取得など)のテストを追加

t0k6 and others added 6 commits June 17, 2026 17:28
- playwright-official-docs/ 独立サブディレクトリとCLIを追加
- stable sidebar/MDX取得とTypeScript/Node.js向け前処理を実装
- ページ単位出力とNotebookLM向けbundleを冪等生成
- MDX idとファイル名の不一致をfrontmatter索引で解決
- fixtureベースのユニット/統合テストを追加

Co-authored-by: Cursor <cursoragent@cursor.com>
- MDX取得の二重fetchをキャッシュ索引で解消
- outDirとfixtureDirのリポジトリ内パス検証を追加
- ページ番号の動的ゼロ埋めとTabsの反復展開を実装
- 重複doc idの警告と関連テストを追加

Co-authored-by: Cursor <cursoragent@cursor.com>
- writeAtomicallyでrename失敗時に既存出力をバックアップから復元
- LiteYouTube等の自己終了JSXコンポーネントを前処理で除去
- sidebar doc idの形式検証を追加

Co-authored-by: Cursor <cursoragent@cursor.com>
- writeAtomicallyでpromote成功後のバックアップ削除失敗を成功扱いにし、tmpDir誤削除を防止
- categoryToSlugとbundleFileNameでbundle出力ファイル名を安全化
- fetchでsidebarUrl・download_url・mdxBaseUrlの許可ホスト検証を追加
- 上記挙動をカバーするユニットテストを追加

Co-authored-by: Cursor <cursoragent@cursor.com>
- buildMdxCatalog/loadMdxにrepoRootを渡しrealpath基準でmdx配下に拘束
- ファイル名・stemを^[a-z0-9-]+$で検証しresolveWithinRepoでsymlink経由の逸脱を拒否
- 不安全なfixtureファイル名の除外とassertSafeMdxStemのユニットテストを追加

Co-authored-by: Cursor <cursoragent@cursor.com>
- removeImportsAndComponentLinesがフェンス境界を追跡しMDX importのみ除去
- removedImports統計を実際に削除した行数に修正
- writing-tests fixtureのコード例import保持をユニット/統合テストで検証

Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitai Bot commented Jun 17, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: f2a2baa7-3c0e-4bb7-9f3f-82cd8a3a1091

📥 Commits

Reviewing files that changed from the base of the PR and between 9e8d126 and 462d5ae.

📒 Files selected for processing (5)
  • playwright-official-docs/src/config.mjs
  • playwright-official-docs/src/export.mjs
  • playwright-official-docs/src/preprocess.mjs
  • test/unit/playwright-docs-config.test.mjs
  • test/unit/playwright-docs-preprocess.test.mjs

📝 Walkthrough

Walkthrough

Playwright 公式ドキュメントを NotebookLM / Gemini 向けに取得・前処理・保存する新規ツール playwright-official-docs/ を追加した。サイドバー解析・MDX フェッチ・Tabs 展開等の前処理・カテゴリ別バンドル生成・原子的ファイル書き込みの各モジュールと CLI を実装し、ユニット/統合テストも同時に追加した。

Changes

playwright-official-docs エクスポートツール

Layer / File(s) Summary
プロジェクト配線とデフォルト設定
.gitignore, README.md, package.json, eslint.config.js, playwright-official-docs/README.md, playwright-official-docs/config.default.json, playwright-official-docs/src/paths.mjs
出力ディレクトリの gitignore ルール追加、npm スクリプト 2 件追加、ESLint 対象拡張、デフォルト設定 JSON(URL 群・baselineDocIds)新規追加、パス検証の再エクスポート、ツール機能説明ドキュメント追加。
サイドバー解析・URL 差分・バンドル生成
playwright-official-docs/src/sidebar.mjs, playwright-official-docs/src/url-review.mjs, playwright-official-docs/src/bundle.mjs
extractDocsPages でサイドバー JSON からページ配列を抽出、diffDocIds/buildUrlReviewMarkdown でベースラインとの差分 Markdown を生成、buildCategoryBundle/buildProjectIndex でカテゴリ別バンドルとインデックスを組み立てる。
MDX フェッチ・カタログ・前処理パイプライン
playwright-official-docs/src/fetch.mjs, playwright-official-docs/src/preprocess.mjs
buildMdxCatalog・loadMdx が fixture またはリモートから MDX を取得してキャッシュし、preprocessMdx が frontmatter 解析・Tabs 展開・JSX 除去・API フッター削除・画像注記化を順に適用して NotebookLM 向け Markdown を返す。
原子的 FS ユーティリティと設定管理
playwright-official-docs/src/fs-utils.mjs, playwright-official-docs/src/config.mjs
writeAtomically が PID 付き一時ディレクトリ経由でバックアップ退避・昇格・復元を実装、validateConfig が必須フィールドと repoRoot 境界を検証し、loadDefaultConfig・mergeConfig が設定を読み込む。
エクスポートオーケストレーションと CLI
playwright-official-docs/src/export.mjs, playwright-official-docs/src/cli.mjs, playwright-official-docs/bin/export-playwright-docs.mjs
runExport が全モジュールを統合して pages/・notebooklm/・補助 Markdown・manifest.json を生成、CLI が --check(dry-run)・--fixture-dir を解析して runExport を起動する。
フィクスチャとテストスイート
test/fixtures/playwright-docs/*, test/unit/playwright-docs-*.test.mjs, test/integration/playwright-docs-cli.test.mjs
MDX フィクスチャ 3 件とサイドバー JSON を追加、bundle・config・fetch・fs-utils・preprocess・sidebar のユニットテストおよび CLI 統合テスト(dry-run・冪等性・パストラバーサル拒否)を実装。

Sequence Diagram(s)

sequenceDiagram
  participant CLI as cli.mjs
  participant Config as config.mjs
  participant Fetch as fetch.mjs
  participant Preprocess as preprocess.mjs
  participant Bundle as bundle.mjs
  participant Export as export.mjs
  participant FS as fs-utils.mjs

  CLI->>Config: loadDefaultConfig() / validateConfig()
  Config-->>CLI: config
  CLI->>Fetch: loadSidebar(config, repoRoot)
  Fetch-->>CLI: sidebar JSON
  CLI->>Fetch: buildMdxCatalog(config, repoRoot)
  Fetch-->>CLI: MdxIndex
  CLI->>Export: runExport(config, {dryRun, repoRoot})
  loop 各ページ
    Export->>Fetch: loadMdx(config, id, index, repoRoot)
    Fetch-->>Export: {content, stem, rawUrl}
    Export->>Preprocess: preprocessMdx(content, page, options)
    Preprocess-->>Export: {markdown, stats}
  end
  Export->>Bundle: buildCategoryBundle / buildProjectIndex
  Bundle-->>Export: Markdown
  Export->>FS: writeAtomically(outDir, writer)
  FS-->>Export: 完了(pages/ notebooklm/ manifest.json)
  Export-->>CLI: {pageCount, bundleCount, urlUnchanged}
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐰 ウサギのパイプライン完成!
MDX を跳ねて集め、
Tabs をぴょんと展開し、
原子的に書き込んで、
NotebookLM へ届けるよ 📚✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR のタイトルはファイルの目的やツール機能を明確に説明し、主要な変更内容を的確に反映しています。
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/playwright-docs-notebooklm-export

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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f24ca0e995

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

*/
export function removeJsxComponents(body) {
return body
.replace(/<[A-Z][A-Za-z0-9]*\b[^>]*\/>/g, "")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve JSX inside fenced code examples

When a docs page contains a fenced React/TSX example with a self-closing component, this global replacement runs after the fence-aware import pass and removes the JSX from the code sample as if it were MDX chrome. For example, component-testing examples such as await mount(<App />) become await mount(), so the generated NotebookLM/page output corrupts runnable code instead of preserving the official docs content. This cleanup needs to track code fences or otherwise avoid applying JSX-component stripping inside fenced blocks.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

@codex fix at adb1e9b

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.gitignore:
- Around line 6-8: Add the pattern `playwright-official-docs/output.bak-*/` to
the .gitignore file alongside the existing
`playwright-official-docs/output.tmp-*/` pattern. Since the fs-utils.mjs file
creates backup directories with `outDir.bak-${process.pid}` and silently
suppresses errors during backup deletion, these backup directories can remain
untracked in the repository. The .bak-* pattern should be excluded from version
control just like the temporary output directories are already being excluded.

In `@playwright-official-docs/src/cli.mjs`:
- Around line 35-40: The current validation for the --fixture-dir option only
checks if the value is falsy, but it doesn't validate that the provided value is
not another option flag. When retrieving the value from argv[fixtureIdx + 1] in
the fixtureDir validation block, add an additional check to ensure the value
does not start with "--" (which would indicate it's another option rather than a
path). If the value starts with "--", throw an error to prevent option flags
from being incorrectly interpreted as path values.

In `@playwright-official-docs/src/config.mjs`:
- Around line 52-82: The validateConfig function only performs a truthy check on
config.fixtureDir at line 52, which allows non-string values (numbers, booleans,
objects) to pass through. This causes a TypeError when non-string values are
passed to path.isAbsolute in the resolveFixtureDir function. Add explicit type
validation to ensure config.fixtureDir is either a string or null, following the
same validation pattern used for other required fields in the validateConfig
function (similar to what is done around line 41), to prevent non-string values
from reaching path.isAbsolute.

In `@playwright-official-docs/src/export.mjs`:
- Around line 33-41: The extractTitle function's regex pattern is matching
title: lines anywhere in the markdown document instead of restricting to the
frontmatter block at the beginning. Modify the function to first extract only
the frontmatter section (the YAML block typically delimited at the start of the
markdown), then apply the title regex pattern only to that extracted frontmatter
section. This prevents false matches on title: strings that may appear in the
document body or code blocks. Ensure the frontmatter extraction handles the
typical delimiters used in markdown files.

In `@playwright-official-docs/src/fetch.mjs`:
- Around line 89-93: The loadSidebar function lacks symlink containment
validation when reading sidebar.json, while the readFixtureMdx function properly
implements this check. Add a call to resolveWithinRepo(file, repoRoot) in the
loadSidebar function before performing fs.readFile on the sidebar.json file
path, ensuring the resolved path is validated to be within the repository root,
similar to how readFixtureMdx handles this to prevent symlink escape attacks.
- Around line 73-80: The fetchText function and the fetch call at Line 151 lack
timeout configuration, which can cause the export process to hang indefinitely
during network issues. Add an AbortSignal with a 15-second timeout to both fetch
calls by including a signal property in the options object passed to fetch. To
avoid duplication across both locations, consider refactoring the fetch logic
into a shared helper function that handles the timeout configuration
consistently.

In `@playwright-official-docs/src/preprocess.mjs`:
- Around line 158-177: The functions removeJsxComponents and replaceImages are
applying global text replacements without checking for code fence boundaries,
which breaks code examples inside markdown code blocks that contain JSX tags or
image syntax. Refactor both functions to implement fence boundary tracking
similar to how removeImportsAndComponentLines handles fences, so that regex
replacements only occur on content outside of code fences (identified by triple
backtick markers), and content within fences is preserved unchanged.
- Around line 105-110: The selectTabContent function and other related functions
directly access properties of the options parameter without providing default
values, causing a TypeError when these functions are called without passing
options. Add a default value (an empty object or an object with appropriate
defaults) to the options parameter in the function signatures for
selectTabContent and the other functions mentioned in the "Also applies to"
section to prevent crashes when options is undefined or not provided.

In `@test/integration/playwright-docs-cli.test.mjs`:
- Around line 84-89: The idempotency test does not verify that the runExport
function calls succeed before comparing file contents. Capture the return value
from both runExport calls (the first call on line 84 and the second call on line
87) and explicitly assert that the exit code equals 0 for both executions. This
ensures the test fails if either export operation fails, rather than passing
simply because leftover files exist and match.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 3f4c98ce-ef52-46ce-8068-d7891bc959bc

📥 Commits

Reviewing files that changed from the base of the PR and between 65467cc and f24ca0e.

📒 Files selected for processing (28)
  • .gitignore
  • README.md
  • eslint.config.js
  • package.json
  • playwright-official-docs/README.md
  • playwright-official-docs/bin/export-playwright-docs.mjs
  • playwright-official-docs/config.default.json
  • playwright-official-docs/src/bundle.mjs
  • playwright-official-docs/src/cli.mjs
  • playwright-official-docs/src/config.mjs
  • playwright-official-docs/src/export.mjs
  • playwright-official-docs/src/fetch.mjs
  • playwright-official-docs/src/fs-utils.mjs
  • playwright-official-docs/src/paths.mjs
  • playwright-official-docs/src/preprocess.mjs
  • playwright-official-docs/src/sidebar.mjs
  • playwright-official-docs/src/url-review.mjs
  • test/fixtures/playwright-docs/mdx/intro.mdx
  • test/fixtures/playwright-docs/mdx/languages.mdx
  • test/fixtures/playwright-docs/mdx/writing-tests.mdx
  • test/fixtures/playwright-docs/sidebar.json
  • test/integration/playwright-docs-cli.test.mjs
  • test/unit/playwright-docs-bundle.test.mjs
  • test/unit/playwright-docs-config.test.mjs
  • test/unit/playwright-docs-fetch.test.mjs
  • test/unit/playwright-docs-fs-utils.test.mjs
  • test/unit/playwright-docs-preprocess.test.mjs
  • test/unit/playwright-docs-sidebar.test.mjs

Comment thread .gitignore
Comment thread playwright-official-docs/src/cli.mjs
Comment thread playwright-official-docs/src/config.mjs
Comment thread playwright-official-docs/src/export.mjs Outdated
Comment thread playwright-official-docs/src/fetch.mjs
Comment thread playwright-official-docs/src/fetch.mjs
Comment thread playwright-official-docs/src/preprocess.mjs Outdated
Comment thread playwright-official-docs/src/preprocess.mjs
Comment thread test/integration/playwright-docs-cli.test.mjs Outdated
t0k6 and others added 2 commits June 17, 2026 23:29
- コードフェンス外のみJSX/画像変換する共通ヘルパを追加
- fixture sidebar読込にcontainment検証とfetch timeoutを追加
- CLI引数・fixtureDir型検証とbak出力ディレクトリのgitignoreを追加
- 関連ユニット/統合テストを追加・更新

Co-authored-by: Cursor <cursoragent@cursor.com>
- CLIランチャーでNode 18未満を検出し、cli.mjs読込前に要件エラーを表示
- package.jsonにengines.node >=18を追加し、実行要件を明示

Co-authored-by: Cursor <cursoragent@cursor.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@playwright-official-docs/src/config.mjs`:
- Around line 49-55: The current validation for config.fixtureDir only checks
for non-string types, allowing empty strings to pass through which then silently
fail at the truthy check on Line 60. Update the validation logic in the
fixtureDir check to additionally reject empty strings as invalid input. The
condition should ensure that if fixtureDir is a string, it must be non-empty,
while still allowing null and undefined values. Add a check to throw an error
when fixtureDir is an empty string, making the error message clear that only
null, undefined, or non-empty strings are acceptable.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 30205bdc-95fe-4811-8821-f196530624ea

📥 Commits

Reviewing files that changed from the base of the PR and between f24ca0e and 9e8d126.

📒 Files selected for processing (13)
  • .gitignore
  • package.json
  • playwright-official-docs/bin/export-playwright-docs.mjs
  • playwright-official-docs/src/cli.mjs
  • playwright-official-docs/src/config.mjs
  • playwright-official-docs/src/export.mjs
  • playwright-official-docs/src/fetch.mjs
  • playwright-official-docs/src/preprocess.mjs
  • test/integration/playwright-docs-cli.test.mjs
  • test/unit/playwright-docs-cli.test.mjs
  • test/unit/playwright-docs-config.test.mjs
  • test/unit/playwright-docs-fetch.test.mjs
  • test/unit/playwright-docs-preprocess.test.mjs

Comment thread playwright-official-docs/src/config.mjs Outdated
- languageTab が typescript のとき ts タブを優先選択するよう照合順を修正
- frontmatter 限定の title 抽出に変更し本文の title: 行の誤マッチを防止
- fixtureDir の空文字・空白のみを検証で明示拒否
- 関連ユニットテストを追加

Co-authored-by: Cursor <cursoragent@cursor.com>
@t0k6
t0k6 merged commit b14ce14 into main Jun 19, 2026
1 check passed
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.

1 participant