diff --git a/docs/src/writing-tests-js.md b/docs/src/writing-tests-js.md index 0e16409e74..ef489c9118 100644 --- a/docs/src/writing-tests-js.md +++ b/docs/src/writing-tests-js.md @@ -31,7 +31,7 @@ timeouts and racy checks in their tests altogether. Take a look at the following example to see how to write a test. -```js +```js title="tests/example.spec.ts" import { test, expect } from '@playwright/test'; test('has title', async ({ page }) => { @@ -152,7 +152,7 @@ Here is the list of the most popular async assertions. Note that there are [many Playwright Test is based on the concept of [test fixtures](./test-fixtures.md) such as the [built in page fixture](./test-fixtures#built-in-fixtures), which is passed into your test. Pages are isolated between tests due to the Browser Context, which is equivalent to a brand new browser profile, where every test gets a fresh environment, even when multiple tests run in a single Browser. -```js +```js title="tests/example.spec.ts" test('basic test', async ({ page }) => { ... ``` @@ -161,7 +161,7 @@ test('basic test', async ({ page }) => { You can use various [test hooks](./api/class-test.md) such as `test.describe` to declare a group of tests and `test.beforeEach` and `test.afterEach` which are executed before/after each test. Other hooks include the `test.beforeAll` and `test.afterAll` which are executed once per worker before/after all tests. -```js +```js title="tests/example.spec.ts" import { test, expect } from "@playwright/test"; test.describe("navigation", () => { diff --git a/utils/markdown.js b/utils/markdown.js index 2a217a7aad..9adaf6248d 100644 --- a/utils/markdown.js +++ b/utils/markdown.js @@ -45,6 +45,7 @@ * type: 'code', * lines: string[], * codeLang: string, + * title?: string, * }} MarkdownCodeNode */ /** @typedef {MarkdownBaseNode & { @@ -163,11 +164,13 @@ function buildTree(lines) { // Remaining items respect indent-based nesting. const [, indent, content] = /** @type {string[]} */ (line.match('^([ ]*)(.*)')); if (content.startsWith('```')) { + const [codeLang, title] = parseCodeBlockMetadata(content); /** @type {MarkdownNode} */ const node = { type: 'code', lines: [], - codeLang: content.substring(3) + codeLang, + title, }; line = lines[++i]; while (!line.trim().startsWith('```')) { @@ -249,6 +252,18 @@ function buildTree(lines) { return root.children; } +/** + * @param {String} firstLine + * @returns {[string, string|undefined]} + */ +function parseCodeBlockMetadata(firstLine) { + const withoutBackticks = firstLine.substring(3); + const match = withoutBackticks.match(/ title="(.+)"$/); + if (match) + return [withoutBackticks.substring(0, match.index), match[1]]; + return [withoutBackticks, undefined]; +} + /** * @param {string} content */ @@ -312,7 +327,7 @@ function innerRenderMdNode(indent, node, lastNode, result, options) { if (node.type === 'code') { newLine(); - result.push(`${indent}\`\`\`${node.codeLang}`); + result.push(`${indent}\`\`\`${node.codeLang}${node.title ? ' title="' + node.title + '"' : ''}`); for (const line of node.lines) result.push(indent + line); result.push(`${indent}\`\`\``);