贡献
🌐 Contributing
首先,感谢你对 Puppeteer 的兴趣!我们非常乐意接受你的补丁和贡献!
🌐 First of all, thank you for your interest in Puppeteer! We'd love to accept your patches and contributions!
贡献者许可协议
🌐 Contributor License Agreement
对本项目的贡献必须附有贡献者许可协议。你(或你的雇主)保留对你所做贡献的版权,这只是授予我们使用和重新分发你贡献的一部分项目的许可。请访问<https://cla.developers.google.com/>查看你当前的协议或签署新的协议。
🌐 Contributions to this project must be accompanied by a Contributor License Agreement. You (or your employer) retain the copyright to your contribution, this simply gives us permission to use and redistribute your contributions as part of the project. Head over to <https://cla.developers.google.com/> to see your current agreements on file or to sign a new one.
通常你只需提交一次 CLA,因此如果你已经提交过一次(即使是针对不同的项目),你可能不需要再次提交。
🌐 You generally only need to submit a CLA once, so if you've already submitted one (even if it was for a different project), you probably don't need to do it again.
立即开始
🌐 Getting started
-
克隆这个存储库
git clone https://github.com/puppeteer/puppeteer
cd puppeteeror
-
安装依赖
npm install
# Or to download Firefox by default
PUPPETEER_BROWSER=firefox npm install -
构建所有包
npm run build -
运行所有测试
npm test
构建单个包
🌐 Building a single package
要构建单个包,你可以运行:
🌐 To build a single package, you can run:
npm run build --workspace <package> # e.g. puppeteer
这将自动构建所有依赖的包,因此指定单个包就足够了。这一切都归功于 wireit,它的行为类似于 GNU Make。
🌐 This will build all dependent packages automatically, so specifying a single package is sufficient. This is all possible due to wireit which behaves similar to GNU Make.
监视模式
🌐 Watch mode
要持续构建包,你可以运行:
🌐 To continuously build a package, you can run:
npm run build --watch --workspace <package> # e.g. puppeteer
你必须只指定一个要监视的软件包,否则事情将不会按预期工作。正如上文所述,由于 wireit,当发生更改时,所有依赖都将被构建或重新构建(如有必要)。
🌐 You have to only specify a single package to watch else things will not work as expected As stated above because of wireit when a change happens all dependencies will be build or rebuild (if needed).
删除旧的工件
🌐 Removing stale artifacts
某些生成的工件(例如 packages/puppeteer-core/src/types.ts)可能会过时,因为这些工件依赖于复杂的条件(例如不同文件的名称),这些条件无法被构建系统捕获。要清理工件,你可以运行
🌐 It's possible some generated artifacts (such as
packages/puppeteer-core/src/types.ts) can become stale since these artifacts
rely on complex conditions (such as names of distinct files) that cannot be
captured by the build system. To clean artifacts, you can run
npm run clean
# or specify the package
npm run clean --workspace <package>
综合测试
🌐 Comprehensive testing
除了 npm test,还有其他几个npm 脚本 通常通过 CI 检查:
🌐 Outside of npm test, there are several other
npm scripts that are
usually check through CI:
test-install- 测试puppeteer和puppeteer-core是否正确安装并可正常使用。test-types- 使用tsd测试puppeteer中的 TypeScript 类型。test:chrome:**- 在 Chrome 上测试puppeteer。test:firefox:**- 在 Firefox 上测试puppeteer。unit- 运行单元测试。
默认的 npm test 会运行 test:{chrome,firefox}:headless,通常这是足够的。
🌐 The default npm test runs test:{chrome,firefox}:headless which is generally
sufficient.
Puppeteer 在 Mocha 之上使用一个自定义测试运行器,该运行器会查阅 TestExpectations.json 来判断给定的测试结果是否符合预期。有关测试运行器的更多信息,请参见 tools/mocha-runner。
🌐 Puppeteer uses a custom test runner on top of Mocha that consults the
TestExpectations.json
to see if a given test result is expected or not. See more info about the test
runner in
tools/mocha-runner.
单元测试
🌐 Unit tests
仅测试代码(不运行浏览器)的测试放置在它们所测试的类旁,并使用 Node 测试运行器运行(需要 Node 20 以上版本):
🌐 Tests that only test code (without the running browser) are put next to the classes they test and run using the Node test runner (requires Node 20+):
npm run unit
代码审查
🌐 Code reviews
所有提交,包括项目成员的提交,都需要进行审查。我们使用 GitHub 拉取请求来进行此操作。有关使用拉取请求的更多信息,请查阅 GitHub 帮助。
🌐 All submissions, including submissions by project members, require review. We use GitHub pull requests for this purpose. Consult GitHub Help for more information on using pull requests.
代码风格
🌐 Code Style
我们的编码风格完全定义在 eslint.config (ESLint) 和 .prettierrc.cjs (Prettier) 中。
🌐 Our coding style is fully defined in
eslint.config
(ESLint) and
.prettierrc.cjs
(Prettier).
代码会自动检查拉取请求,你也可以通过运行以下命令手动检查你的代码:
🌐 Code is checked for PRs automatically and you can check your code manually by running:
npm run lint
如果返回一些错误,你可以尝试使用以下方法修复它们:
🌐 If some errors are returned, you can attempt to fix them using:
npm run format
项目结构
🌐 Project structure
以下是 Puppeteer 中主要文件夹的说明:
🌐 The following is a description of the primary folders in Puppeteer:
packages包含所有公共源代码。test包含所有测试源代码。test-d包含使用tsd的类型测试。tools包含用于架构等的各种脚本。tools/mocha-runner- 包含我们的测试运行程序的源代码。
API 指南
🌐 API guidelines
编写新的 API 方法时,请考虑以下事项:
🌐 When authoring new API methods, consider the following:
- 仅暴露必要的信息。如有疑问,不要暴露新的信息。
- 方法的使用有利于 getter/setter。
- 唯一的例外是命名空间,例如
page.keyboard和page.coverage
- 唯一的例外是命名空间,例如
- 所有字符串字面量必须是小写。这包括事件名称和选项值。
- 除非有极端需求,否则避免添加“糖”API(可以在用户空间轻松实现的API)。
提交消息
🌐 Commit messages
提交信息应遵循 Conventional Commits 格式。
🌐 Commit messages should follow the Conventional Commits format.
特别是,破坏性更改应在提交信息的底部明确标注为“BREAKING CHANGE:”。例如:
🌐 In particular, breaking changes should clearly be noted as “BREAKING CHANGE:” in the commit message footer. Example:
fix(page): fix page.pizza method
This patch fixes page.pizza so that it works with iframes.
Issues: #123, #234
BREAKING CHANGE: page.pizza now delivers pizza at home by default.
To deliver to a different location, use the "deliver" option:
`page.pizza({deliver: 'work'})`.
编写文档
🌐 Writing documentation
文档是通过 npm run docs 从 TSDoc 注释生成的。它在合并时会自动发布到我们的文档网站,并在发布时进行版本控制。
🌐 Documentation is generated from TSDoc comments via npm run docs. It is automatically
published to our documentation site on merge and gets versioned on release.
这意味着你不应该手动更改文件 docs/api 中的 Markdown。
🌐 This means that you should not change the markdown in files docs/api manually.
编写 TSDoc 注释
🌐 Writing TSDoc comments
对 Puppeteer 的每一次更改都应使用 TSDoc 注释进行详细记录。有关确切语法的信息,请参阅 API Extractor 文档。
🌐 Each change to Puppeteer should be thoroughly documented using TSDoc comments. Refer to the API Extractor documentation for information on the exact syntax.
- 每个新方法都需要根据它是否属于公共 API 添加
@public或@internal作为标签。 - 将每行注释保持在不超过90个字符(如果超过,ESLint会提醒你)。如果你是VSCode用户,强烈推荐使用 Rewrap 插件!
在本地运行文档站点
🌐 Running the documentation site locally
- 从根本上,用
npm i --ignore-scripts安装所有依赖。 - 运行
npm run docs,它将在puppeteer/docs/api上生成所有.md文件。 - 在
puppeteer/website中运行npm i。 - 在
puppeteer/website中运行npm start。
添加新的依赖
🌐 Adding new dependencies
对于所有依赖(安装和开发):
🌐 For all dependencies (both installation and development):
- **如果所需功能容易实现,**不要添加依赖。
- 如果添加依赖,它应该维护良好且值得信赖。
引入新的安装依赖的障碍特别高:
🌐 A barrier for introducing new installation dependencies is especially high:
- 除非对项目的成功至关重要,否则不要添加安装依赖。
对于与环境无关的依赖,还有额外的考虑事项。详情请参见 third_party/README.md。
🌐 There are additional considerations for dependencies that are environment
agonistic. See the
third_party/README.md
for details.
测试技巧
🌐 Testing tips
- 每个功能都应该附有测试。
- 每个公共 api 事件/方法都应该伴随一个测试。
- 测试不应依赖于外部服务。
- 测试应该在所有三个平台上运行:Mac、Linux 和 Windows。这对于截图测试尤其重要。
如果预计某个测试在某些配置上会失败或变得不稳定,请更新 TestExpectations.json 以反映这一点。关于 TestExpectations.json 的更多信息,请参阅 tools/mocha-runner。
🌐 If a test is expected to fail on certain configurations or became flaky, update
TestExpectations.json
to reflect that. See more info about TestExpectations.json in
tools/mocha-runner.
API 覆盖范围
🌐 API Coverage
每个公共 API 方法或事件都应该至少在测试中调用一次。为了确保这一点,主要的 test 命令在测试期间运行覆盖率。
🌐 Every public API method or event should be called at least once in tests. To
ensure this, the main test command runs coverage during testing.
调试 Puppeteer
🌐 Debugging Puppeteer
请参阅 调试技巧。
🌐 See Debugging Tips.
通过 VSCode 调试 Puppeteer 测试
🌐 Debugging Puppeteer tests via VSCode
将提供的默认 .vscode/launch.template.json 复制到 .vscode/launch.json,然后使用集成的 VSCode 调试器进行测试调试。
🌐 Copy the provided default .vscode/launch.template.json to .vscode/launch.json and then use the integrated VSCode debugger to debug test.
请记住在启动之前通过以下方式构建测试:
🌐 Remember to build test before launching via:
npm run build --workspace @puppeteer-test/test
对于项目维护人员
🌐 For Project Maintainers
推出新的 Chrome 版本
🌐 Rolling new Chrome version
有一个GitHub 操作每天运行一次。该操作有一个手动触发器,可以在操作选项卡中找到。
🌐 There is a GitHub action that runs once per day. The action has a manual trigger that can be found on the Actions Tab.
手册说明
🌐 Manual instructions
你可以在本地运行 tools/update_browser_revision.mjs 并尝试查看是否有任何更改需要提交。
🌐 You can run the tools/update_browser_revision.mjs locally
and try see if any changes need to be committed.
注意:你可能需要运行
node --experimental-fetch tools/update_browser_revision.mjs,因为该脚本依赖fetch
以下步骤是上述脚本的手动版本。
🌐 The following steps are manual version of the script above.
- 通过 https://googlechromelabs.github.io/chrome-for-testing/ 或 https://chromiumdash.appspot.com/ 找到合适的 Chrome
revision和version。 - 用找到的
version数字更新packages/puppeteer-core/src/revisions.ts。 - 使用新的 Chrome 到 Puppeteer 的
version映射更新versions.json,并使用列表中的下一个更新lastMaintainedChromeVersion。 - 运行
npm run check。如果失败,请将packages/puppeteer-core/package.json更新到预期的devtools-protocol版本,然后运行npm install来生成更新的package-lock.json。 - 运行
npm run clean、npm install和npm run build。 - 运行
npm test并确保所有测试通过。如果测试失败,使用 bisect 找出故障的上游原因,然后根据情况要么相应地更新测试期望(如果这是预期的更改),要么在 Puppeteer 中处理这些更改(如果不希望改变 Puppeteer 的可观察行为)。 - 提交并推送你的更改并打开拉取请求。提交信息必须包含
Chrome <version>格式的版本,以确保 pptr.dev 可以正确解析,例如feat(chrome): roll to Chrome 90.0.4427.0。
平分上游变化
🌐 Bisecting upstream changes
要对 Chrome/Chromium 更改进行二分查找,请使用 https://www.chromium.org/developers/bisect-builds-py/。
🌐 For bisecting Chrome/Chromium changes use https://www.chromium.org/developers/bisect-builds-py/.
python3 <path-to-chromium-checkout>/tools/bisect-builds.py -g <known-good> -b <known-bad> -cft -v --verify-range --not-interactive -c "BINARY=%p npm run test:chrome:<test-type>"
或者在 tools/bisect.mjs 中运行封装器,该封装器将上述功能封装用于 Puppeteer 测试。
🌐 Or run the wrapper in tools/bisect.mjs that warps the above functionality for Puppeteer tests.
# From Puppeteer repo root
node tools/bisect.mjs -g <known-good> -b <known-bad>
发布到 npm
🌐 Releasing to npm
我们使用 release-please 来自动化发布。当需要进行发布时,请检查我们 拉取请求 中的发布 PR 并合并它。
🌐 We use release-please to automate releases. When a release should be done, check for the release PR in our pull requests and merge it.
如果 Release Please 失败
🌐 In case Release Please fails
如果 release-please 失败,需要执行以下操作:
🌐 In the event release-please fails, the following needs to be done:
-
更新每个应该发布的包中 CHANGELOG 中缺失的任何内容。例如,如果标题缺失,你可能需要添加
-
对于木偶师来说:
## [{NEW_VERSION}](https://github.com/puppeteer/puppeteer/compare/v{PREVIOUS_VERSION}...v{NEW_VERSION}) ({CURRENT_DATE})` -
对于其他包:
## [{NEW_VERSION}](https://github.com/puppeteer/puppeteer/compare/{PACKAGE_FOLDER_NAME}-v{PREVIOUS_VERSION}...{PACKAGE_FOLDER_NAME}-v{NEW_VERSION}) ({CURRENT_DATE})
-
-
为每个软件包创建一个 GitHub 发布,遵循之前发布的做法。
错误分类指南
🌐 Bug triage guidelines
检查没有 confirmed 或 needs-feedback 标签的传入错误报告:
- 确保该问题被标记为
bug或feature。 - 如果问题没有明确的复现步骤或你无法复现,请要求提供复现步骤并设置
needs-feedback标签。 - 跟进你之前要求反馈的问题(当用户响应时,你应该在 GitHub 上收到通知)。
- 如果用户不提供反馈,问题最终将被过时的机器人关闭。
- 如果你能够重现该问题,请添加标签
confirmed。 - 如果错误发生在 Chromium 端,请创建一个对应的 crbug.com 问题,在 GitHub 问题上标记
upstream标签,并在评论中发布 crbug.com 的链接。 - 如果问题与 Puppeteer 或 Chromium 无关,请关闭该问题。
- 如果问题是关于缺失/错误的文档,请将其标记为
documentation。
PDF 的问题:
🌐 Issues with PDFs:
- 如果使用常规打印对话框和/或带界面的方式问题仍然出现,请 针对
Blink>Layout组件在 crbug.com 提交问题。 - 如果问题仅出现在无头模式,请在 crbug.com 上针对
Internals>Headless组件提交问题。