playwright-release-notes
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseRelease notes
发布说明
In this skill, is the release (for example ).
1.xx1.64Every release has a section in four files in :
## Version 1.xxdocs/src/| Language | Notes | Docs base URL | GitHub release in |
|---|---|---|---|
| Node.js | | | |
| Python | | | |
| Java | | | |
| .NET | | | |
Write the Node.js notes and the three translations in the same PR, so every language has its notes when it starts its release. The language repos then add only their own significant changes, and each one writes its GitHub release from its section (step 3).
在本 skill 中, 表示版本号(例如 )。
1.xx1.64每个版本在 下的四个文件中都有一个 章节:
docs/src/## Version 1.xx| 语言 | 说明 | 文档基础 URL | GitHub 发布仓库 |
|---|---|---|---|
| Node.js | | | |
| Python | | | |
| Java | | | |
| .NET | | | |
在同一个 PR 中编写 Node.js 说明和另外三个翻译版本,这样每种语言开始发布时就已经有对应的发布说明。随后,各语言仓库只需添加自身的重要变更,并各自根据对应章节编写 GitHub Release(步骤 3)。
1. Node.js notes
1. Node.js 说明
In , add a section above the previous version, and use previous versions as a guide:
docs/src/release-notes-js.md## Version 1.xx- Highlights come first, each with an emoji heading and a short sample. Ask teammates for help with them.
- Then with
### New APIsgroups,####,### Breaking Changes ⚠️and### Announcements. Print the browser versions with### Browser Versions.node utils/print_versions.js - Refer to APIs with docs link macros: ,
[`method: Page.frameLocator`],[`property: Page.webmcp`],[`event: Page.dialogClosed`],[`option: Tracing.start.ariaSnapshots`]. Each language's docs show them with that language's names.[Locator] - Link other docs pages with relative paths: .
[test locks](./test-parallel.md#test-locks)
在 中,在上一个版本之上添加 章节,并参考之前的版本:
docs/src/release-notes-js.md## Version 1.xx- 重点变更放在最前面,每项使用 emoji 标题和简短示例。可以请同事协助编写。
- 随后添加 (使用
### New APIs分组)、####、### Breaking Changes ⚠️和### Announcements。使用### Browser Versions打印浏览器版本。node utils/print_versions.js - 引用 API 时使用文档链接宏:、
[`method: Page.frameLocator`]、[`property: Page.webmcp`]、[`event: Page.dialogClosed`]、[`option: Tracing.start.ariaSnapshots`]。各语言文档会使用相应语言的名称显示这些内容。[Locator] - 使用相对路径链接其他文档页面:。
[test locks](./test-parallel.md#test-locks)
2. Python, Java and .NET translations
2. Python、Java 和 .NET 翻译
In each of , and , add a section above the previous version. Translate it from the Node.js section. Compare the sections of the files to see what past translations dropped and changed.
release-notes-python.mdrelease-notes-java.mdrelease-notes-csharp.md## Version 1.xxVersion 1.63For every language:
- Keep the structure: highlights with emoji headings, with
### New APIsgroups,####,### Breaking Changes ⚠️and### Announcements.### Browser Versions - Remove what the language does not have:
- the test runner: ,
@playwright/test, config, fixtures, projects, reporters andtest.*optionsnpx playwright test - UI mode, the HTML report, component testing and the VS Code extension
- TypeScript-only features (generics, JSX, ) and
tsconfigdescriptorsdevices - every API whose excludes the language (
langs,python,java). Checkcsharpinlangs; options shared between methods are defined indocs/src/api/.docs/src/api/params.md
- the test runner:
- Use the language's API where it differs from Node.js:
- A language-specific option has its own . For example,
langsisrecordVideoFps, while Node.js haslangs: csharp, java, python.recordVideo.fps - renames a member, e.g.
alias-<lang>foralias-java: isVisible.LocatorAssertions.toBeVisible - The generated APIs in sibling checkouts confirm the names: ,
../playwright-python/playwright/sync_api/_generated.pyand../playwright-java/playwright/src/main/java/com/microsoft/playwright/.../playwright-dotnet/src/Playwright/API/Generated/
- A language-specific option has its own
- When a Node.js sample shows a library feature through , show the API call instead. For example, the 1.64 video config became calls to
playwright.config.tsandScreencast.start.Screencast.showActions - Keep API links as docs link macros, and link the language's own option where it differs (). In plain text, use the language's names.
[`option: Browser.newContext.recordVideoFps`] - A relative link must point to a page that exists in the language: pages are Node.js only.
*-js.mdreports broken links for each language.npm run doc - Do not add changes that only a language port made. The language repo adds those to its notes.
Rewrite code samples in each language's style. The workflow checks the syntax of , and snippets.
infrapythonjavacsharp分别在 、 和 中,在上一个版本之上添加 章节。根据 Node.js 章节进行翻译。对比这些文件中的 章节,了解以往翻译删减和更改了哪些内容。
release-notes-python.mdrelease-notes-java.mdrelease-notes-csharp.md## Version 1.xxVersion 1.63对于每种语言:
- 保持结构:使用 emoji 标题的重点变更、(使用
### New APIs分组)、####、### Breaking Changes ⚠️和### Announcements。### Browser Versions - 移除该语言不支持的内容:
- 测试运行器:、
@playwright/test、config、fixtures、projects、reporters 和test.*选项npx playwright test - UI mode、HTML report、component testing 和 VS Code extension
- 仅 TypeScript 支持的功能(generics、JSX、)和
tsconfigdescriptorsdevices - 移除所有 不包含当前语言(
langs、python、java)的 API。检查csharp中的docs/src/api/;方法之间共享的选项定义在langs中。docs/src/api/params.md
- 测试运行器:
- 当 API 与 Node.js 不同时,使用该语言对应的 API:
- 语言专属选项具有自己的 。例如,
langs的recordVideoFps为langs,而 Node.js 使用csharp, java, python。recordVideo.fps - 会重命名成员,例如
alias-<lang>使用LocatorAssertions.toBeVisible。alias-java: isVisible - 相邻检出目录中生成的 API 可确认具体名称:、
../playwright-python/playwright/sync_api/_generated.py和../playwright-java/playwright/src/main/java/com/microsoft/playwright/。../playwright-dotnet/src/Playwright/API/Generated/
- 语言专属选项具有自己的
- 当 Node.js 示例通过 展示某个库功能时,改为展示 API 调用。例如,1.64 的视频配置应改为调用
playwright.config.ts和Screencast.start。Screencast.showActions - API 链接应继续使用文档链接宏;如果选项名称因语言而异,应链接该语言对应的选项()。在纯文本中,使用该语言的名称。
[`option: Browser.newContext.recordVideoFps`] - 相对链接必须指向该语言中存在的页面:页面仅适用于 Node.js。
*-js.md会报告各语言中的失效链接。npm run doc - 不要添加仅由某个语言移植产生的变更。这些内容由相应的语言仓库添加到其发布说明中。
按照每种语言的代码风格重写代码示例。 workflow 会检查 、 和 代码片段的语法。
infrapythonjavacsharpPython
Python
- Use the sync API: . Use snake_case names and Python values (
page.get_by_role("button").click(),True,False).None - Options become keyword arguments: . Objects and arrays become dicts and lists:
page.get_by_role("button", name="Save").size={"width": 1920, "height": 1080} - Aria roles and other string values stay strings: ,
"button"."ai" - Events: . Assertions:
page.on("dialogclosed", handler). Print withexpect(locator).to_have_text([...]).print(...) - Use the names:
alias-python,route.continue_(),locator.or_().page.expect_request() - Commands: write , not
playwright install.npx playwright install
- 使用同步 API:。使用 snake_case 名称和 Python 值(
page.get_by_role("button").click()、True、False)。None - 选项变为关键字参数:。对象和数组分别变为 dict 和 list:
page.get_by_role("button", name="Save")。size={"width": 1920, "height": 1080} - ARIA role 和其他字符串值保持为字符串:、
"button"。"ai" - 事件:。断言:
page.on("dialogclosed", handler)。输出:expect(locator).to_have_text([...])。print(...) - 使用 名称:
alias-python、route.continue_()、locator.or_()。page.expect_request() - 命令:使用 ,不要使用
playwright install。npx playwright install
Java
Java
| Node.js | Java |
|---|---|
| |
| |
options object | options builder |
object literal | value class |
| |
property | getter |
event | |
| |
| the alias, e.g. |
| |
"array", | "list", |
| Node.js | Java |
|---|---|
| |
| |
选项对象 | 选项构建器 |
对象字面量 | 值类 |
| |
属性 | getter |
事件 | |
| |
| 使用别名,例如 |
| |
正文中的 | |
.NET
.NET
| Node.js | .NET |
|---|---|
| |
| |
options object | options initializer |
nested object | |
object literal | |
| |
string-literal union value | enum member |
property | property |
event | |
| |
| |
members with | the alias, e.g. |
union-typed option, e.g. | one property per type, e.g. |
| |
option names in prose ( | |
Open one PR for all four files, titled . After it merges, cherry-pick it to with the skill.
docs: release notes for v1.xxrelease-1.xxplaywright-cherry-pick| Node.js | .NET |
|---|---|
| |
| |
选项对象 | 选项初始化器 |
嵌套对象 | |
对象字面量 | |
| |
字符串字面量 union 值 | 枚举成员 |
属性 | 属性 |
事件 | |
| |
| |
带 | 使用别名,例如 |
union 类型选项,例如作为列表的 | 每种类型使用一个属性,例如 |
| |
正文中的选项名称( | |
为这四个文件创建一个 PR,标题为 。合并后,使用 skill 将其 cherry-pick 到 。
docs: release notes for v1.xxplaywright-cherry-pickrelease-1.xx3. GitHub release markdown
3. GitHub Release Markdown
Each repo publishes the GitHub release for its language, with markdown converted from its section on . Convert the notes yourself:
## Version 1.xxrelease-1.xx-
Leave out theheading. Move every other heading up one level (
## Version 1.xxbecomes###,##becomes####).### -
Replace each link macro with a full link: the language's docs base URL from the table at the top, plus the path below. Use the language's name as the link text:
Macro Path after the docs base URL Node.js Python Java .NET [Locator]api/class-locatorLocatorLocatorLocatorLocator[`method: Page.frameLocator`]api/class-page#page-frame-locatorpage.frameLocator()page.frame_locator()page.frameLocator()Page.FrameLocator()[`method: Page.ariaSnapshot`]api/class-page#page-aria-snapshotpage.ariaSnapshot()page.aria_snapshot()page.ariaSnapshot()Page.AriaSnapshotAsync()[`method: Locator.first`]api/class-locator#locator-firstlocator.first()locator.firstlocator.first()Locator.First[`property: Page.webmcp`]api/class-page#page-webmcppage.webmcppage.webmcppage.webmcp()Page.Webmcp[`event: BrowserContext.dialogClosed`]api/class-browsercontext#browser-context-event-dialog-closedbrowserContext.on('dialogclosed')browser_context.on("dialogclosed")browserContext.onDialogClosed()BrowserContext.DialogClosed[`method: LocatorAssertions.toBeVisible`]api/class-locatorassertions#locator-assertions-to-be-visibleexpect(locator).toBeVisible()expect(locator).to_be_visible()assertThat(locator).isVisible()Expect(Locator).ToBeVisibleAsync()[`option: Page.content.includeShadow`]api/class-page#page-content-option-include-shadow`includeShadow``include_shadow``includeShadow``IncludeShadow`[Playwright MCP](./getting-started-mcp.md)getting-started-mcpPlaywright MCPPlaywright MCPPlaywright MCPPlaywright MCP -
An imagebecomes
in every language.
The page is and the class name in lower case. The anchor is the class and member names in kebab-case, so becomes . Options add , and events add . Anchors use the names from even where a language renames the member, so Java's links to .
class-APIRequestContext.addCookiesapi-request-context-add-cookies-option-<name>-event-<name>docs/src/api/isVisible()#locator-assertions-to-be-visibleThe link text follows the language:
- Node.js: the class in lower camel case (,
page,apiRequestContext). Methods gettestConfig, properties none, events become(), and assertions start withon('<event in lower case>'),expect(locator).orexpect(page)..expect(response). - Python: the class and member in snake_case (,
browser_context). Methods getapi_request_context. A member is a property, without(), if()declares it with_generated.py. Events become@property, and assertions start withon("<event in lower case>").expect(locator). - Java: the class in lower camel case and the member name. Methods and properties get
alias-java, events become(), and assertions start withon<Event>().assertThat(locator). - .NET: the class without the interface (
I,Page) and the member exactly as the generatedAPIRequestContextdeclares it. Async methods take theI<Class>.cssuffix andAsync, sync methods get(), and properties and events get no parentheses. Assertions start with().Expect(Locator).
Check that every link resolves. playwright.dev already documents the release once the Node.js docs roll has landed. It serves minified HTML, so an anchor may appear without quotes ():
id=page-webmcp>bash
grep -oE 'https://playwright\.dev/[^) ]+' <notes-file> | sort -u | while read -r url; do
page=${url%%#*}
html=$(curl -sfL "$page") || { echo "MISSING PAGE $url"; continue; }
if [[ "$url" == *"#"* ]]; then
anchor=${url#*#}
grep -qE "id=\"?${anchor}[\" >]" <<<"$html" || echo "MISSING ANCHOR $url"
fi
doneThen scan for anything that wasn't converted, and for stray spaces inside link text (, ). The first command applies to every language; then run the one for the language. They should print nothing:
[Page. DialogClosed][`HttpCredentialsList `]bash
undefined每个仓库发布对应语言的 GitHub Release,其 Markdown 由 分支中的 章节转换而来。请自行转换说明内容:
release-1.xx## Version 1.xx-
不要保留标题。其余每个标题的层级都上调一级(
## Version 1.xx变为###,##变为####)。### -
将每个链接宏替换为完整链接:使用表格顶部该语言的文档基础 URL,再加上下方路径。使用该语言的名称作为链接文本:
宏 文档基础 URL 之后的路径 Node.js Python Java .NET [Locator]api/class-locatorLocatorLocatorLocatorLocator[`method: Page.frameLocator`]api/class-page#page-frame-locatorpage.frameLocator()page.frame_locator()page.frameLocator()Page.FrameLocator()[`method: Page.ariaSnapshot`]api/class-page#page-aria-snapshotpage.ariaSnapshot()page.aria_snapshot()page.ariaSnapshot()Page.AriaSnapshotAsync()[`method: Locator.first`]api/class-locator#locator-firstlocator.first()locator.firstlocator.first()Locator.First[`property: Page.webmcp`]api/class-page#page-webmcppage.webmcppage.webmcppage.webmcp()Page.Webmcp[`event: BrowserContext.dialogClosed`]api/class-browsercontext#browser-context-event-dialog-closedbrowserContext.on('dialogclosed')browser_context.on("dialogclosed")browserContext.onDialogClosed()BrowserContext.DialogClosed[`method: LocatorAssertions.toBeVisible`]api/class-locatorassertions#locator-assertions-to-be-visibleexpect(locator).toBeVisible()expect(locator).to_be_visible()assertThat(locator).isVisible()Expect(Locator).ToBeVisibleAsync()[`option: Page.content.includeShadow`]api/class-page#page-content-option-include-shadow`includeShadow``include_shadow``includeShadow``IncludeShadow`[Playwright MCP](./getting-started-mcp.md)getting-started-mcpPlaywright MCPPlaywright MCPPlaywright MCPPlaywright MCP -
图像在每种语言中都会转换为
。
页面路径以 开头,后接小写的类名。锚点由类名和成员名转换为 kebab-case,因此 会变成 。选项需追加 ,事件需追加 。即使某种语言重命名了成员,锚点仍使用 中的名称,因此 Java 的 会链接到 。
class-APIRequestContext.addCookiesapi-request-context-add-cookies-option-<name>-event-<name>docs/src/api/isVisible()#locator-assertions-to-be-visible链接文本遵循各语言的规则:
- Node.js: 类名使用 lower camel case(、
page、apiRequestContext)。方法带testConfig,属性不带括号,事件变为(),断言以on('<event in lower case>')、expect(locator).或expect(page).开头。expect(response). - Python: 类和成员使用 snake_case(、
browser_context)。方法带api_request_context。如果()使用_generated.py声明某个成员,则该成员是属性,不带@property。事件变为(),断言以on("<event in lower case>")开头。expect(locator). - Java: 类名使用 lower camel case,成员使用 名称。方法和属性带
alias-java,事件变为(),断言以on<Event>()开头。assertThat(locator). - .NET: 类名不带接口 (
I、Page),成员名称与生成的APIRequestContext中声明的完全一致。异步方法带I<Class>.cs后缀和Async,同步方法带(),属性和事件不带括号。断言以()开头。Expect(Locator).
检查每个链接是否可解析。Node.js 文档上线后,playwright.dev 就会记录该版本。它提供的是压缩后的 HTML,因此锚点可能不带引号出现():
id=page-webmcp>bash
grep -oE 'https://playwright\.dev/[^) ]+' <notes-file> | sort -u | while read -r url; do
page=${url%%#*}
html=$(curl -sfL "$page") || { echo "MISSING PAGE $url"; continue; }
if [[ "$url" == *"#"* ]]; then
anchor=${url#*#}
grep -qE "id=\"?${anchor}[\" >]" <<<"$html" || echo "MISSING ANCHOR $url"
fi
done然后扫描是否有遗漏的未转换内容,以及链接文本中是否存在多余空格(、)。先运行适用于所有语言的第一个命令,再运行对应语言的命令。它们都不应输出任何内容:
[Page. DialogClosed][`HttpCredentialsList `]bash
undefinedevery language
every language
grep -nE '[[^]' <notes-file>
(method|property|event|option|param): |\]\(\./|\[[A-Z][A-Za-z]*\]([^(]|$)|\[[A-Za-z_]+\. |\[]+ grep -nE '[[^]' <notes-file>
(method|property|event|option|param): |\]\(\./|\[[A-Z][A-Za-z]*\]([^(]|$)|\[[A-Za-z_]+\. |\[]+ Python: camelCase names in link text
Python: camelCase names in link text
grep -nE '[[a-z_]+.[a-z_]*[A-Z]|[`[a-z]+[A-Z]' <notes-file>
grep -nE '[[a-z_]+.[a-z_]*[A-Z]|[`[a-z]+[A-Z]' <notes-file>
Java: JS-style events, assertions and properties
Java: JS-style events, assertions and properties
grep -nE ".on('|\b(toBe|toHave|toContain|toMatch)[A-Z]|\bawait\b|\barray\b|\bundefined\b|[[a-z][A-Za-z].[a-z][A-Za-z]](" <notes-file>
grep -nE ".on('|\b(toBe|toHave|toContain|toMatch)[A-Z]|\bawait\b|\barray\b|\bundefined\b|[[a-z][A-Za-z].[a-z][A-Za-z]](" <notes-file>
.NET: lower-case classes or members, JS-style events
.NET: lower-case classes or members, JS-style events
grep -nE ".on('|\bundefined\b|[[a-z][A-Za-z].|[[A-Z][A-Za-z].[a-z]|[Expect([a-z]" <notes-file>
If the conversion shows a problem in the notes themselves, such as an API the language does not have or a sample in the wrong style, fix the notes too (step 2). Otherwise the problem stays on playwright.dev.grep -nE ".on('|\bundefined\b|[[a-z][A-Za-z].|[[A-Z][A-Za-z].[a-z]|[Expect([a-z]" <notes-file>
如果转换过程暴露出发布说明本身的问题,例如某语言不支持的 API 或样式错误的示例,也应修复发布说明(步骤 2)。否则,该问题会保留在 playwright.dev 上。