mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
chore: harden markdown link validation (#30221)
This commit is contained in:
parent
0734d1e733
commit
010bc29a3c
@ -6,9 +6,6 @@
|
||||
Error is raised whenever certain operations are terminated abnormally, e.g.
|
||||
browser closes while [`method: Page.evaluate`] is running. All Playwright exceptions
|
||||
inherit from this class.
|
||||
- [error.message](./class-error.md#errormessage)
|
||||
- [error.name](./class-error.md#errorname)
|
||||
- [error.stack](./class-error.md#errorstack)
|
||||
|
||||
## property: Error.message
|
||||
* since: v1.11
|
||||
|
||||
@ -30,7 +30,7 @@ To add a [GitHub Actions](https://docs.github.com/en/actions) file first create
|
||||
#### You will learn
|
||||
* langs: python, java, csharp
|
||||
|
||||
- [How to run tests on push/pull_request](/ci.md#on-pushpull_request)
|
||||
- [How to run tests on push/pull_request](/ci-intro.md#on-pushpull_request)
|
||||
- [How to view test logs](/ci-intro.md#viewing-test-logs)
|
||||
- [How to view the trace](/ci-intro.md#viewing-the-trace)
|
||||
|
||||
|
||||
@ -80,14 +80,14 @@ npx playwright test --debug
|
||||
```
|
||||
#### Debug one test on all browsers
|
||||
|
||||
To debug one test on a specific line run the test command followed by the name of the test file and the line number of the test you want to debug, followed by the `--debug` flag. This will run a single test in each browser configured in your [`playwright.config`](/test-configuration.md#multiple-browsers) and open the inspector.
|
||||
To debug one test on a specific line run the test command followed by the name of the test file and the line number of the test you want to debug, followed by the `--debug` flag. This will run a single test in each browser configured in your [`playwright.config`](./test-projects.md#configure-projects-for-multiple-browsers) and open the inspector.
|
||||
|
||||
```bash
|
||||
npx playwright test example.spec.ts:10 --debug
|
||||
```
|
||||
#### Debug on a specific browser
|
||||
|
||||
In Playwright you can configure projects in your [`playwright.config`](/test-configuration.md#multiple-browsers). Once configured you can then debug your tests on a specific browser or mobile viewport using the `--project` flag followed by the name of the project configured in your `playwright.config`.
|
||||
In Playwright you can configure projects in your [`playwright.config`](./test-projects.md#configure-projects-for-multiple-browsers). Once configured you can then debug your tests on a specific browser or mobile viewport using the `--project` flag followed by the name of the project configured in your `playwright.config`.
|
||||
|
||||
```bash
|
||||
npx playwright test --project=chromium --debug
|
||||
|
||||
@ -644,7 +644,7 @@ This version was also tested against the following stable channels:
|
||||
|
||||
### New APIs & changes
|
||||
|
||||
- Default assertions timeout now can be changed with [`setDefaultAssertionTimeout`](./test-assertions#playwright-assertions-set-default-assertion-timeout).
|
||||
- Default assertions timeout now can be changed with [`setDefaultAssertionTimeout`](./api/class-playwrightassertions#playwright-assertions-set-default-assertion-timeout).
|
||||
|
||||
### Announcements
|
||||
|
||||
|
||||
@ -262,7 +262,7 @@ test('pass', async ({ page }) => {
|
||||
});
|
||||
```
|
||||
|
||||
See the documentation [for a full example](./test-assertions.md#add-custom-matchers-using-expectextend).
|
||||
See the documentation [for a full example](./test-assertions#add-custom-matchers-using-expectextend).
|
||||
|
||||
### Merge test fixtures
|
||||
|
||||
@ -1753,7 +1753,7 @@ This version was also tested against the following stable channels:
|
||||
### Locator Improvements
|
||||
|
||||
- [`method: Locator.dragTo`]
|
||||
- [`expect(locator).toBeChecked({ checked })`](./test-assertions#locator-assertions-to-be-checked)
|
||||
- [`expect(locator).toBeChecked({ checked })`](./api/class-locatorassertions#locator-assertions-to-be-checked)
|
||||
- Each locator can now be optionally filtered by the text it contains:
|
||||
```js
|
||||
await page.locator('li', { hasText: 'my item' }).locator('button').click();
|
||||
@ -1908,7 +1908,7 @@ Playwright Trace Viewer is now **available online** at https://trace.playwright.
|
||||
- [`testInfo.parallelIndex`](./api/class-testinfo#test-info-parallel-index)
|
||||
- [`testInfo.titlePath`](./api/class-testinfo#test-info-title-path)
|
||||
- [`testOptions.trace`](./api/class-testoptions#test-options-trace) has new options
|
||||
- [`expect.toMatchSnapshot`](./test-assertions#expectvaluetomatchsnapshotname-options) supports subdirectories
|
||||
- [`expect.toMatchSnapshot`](./api/class-genericassertions.md) supports subdirectories
|
||||
- [`reporter.printsToStdio()`](./api/class-reporter#reporter-prints-to-stdio)
|
||||
|
||||
|
||||
@ -2189,25 +2189,25 @@ By default, the timeout for assertions is not set, so it'll wait forever, until
|
||||
|
||||
List of all new assertions:
|
||||
|
||||
- [`expect(locator).toBeChecked()`](./test-assertions#expectlocatortobechecked)
|
||||
- [`expect(locator).toBeDisabled()`](./test-assertions#expectlocatortobedisabled)
|
||||
- [`expect(locator).toBeEditable()`](./test-assertions#expectlocatortobeeditable)
|
||||
- [`expect(locator).toBeEmpty()`](./test-assertions#expectlocatortobeempty)
|
||||
- [`expect(locator).toBeEnabled()`](./test-assertions#expectlocatortobeenabled)
|
||||
- [`expect(locator).toBeFocused()`](./test-assertions#expectlocatortobefocused)
|
||||
- [`expect(locator).toBeHidden()`](./test-assertions#expectlocatortobehidden)
|
||||
- [`expect(locator).toBeVisible()`](./test-assertions#expectlocatortobevisible)
|
||||
- [`expect(locator).toContainText(text, options?)`](./test-assertions#expectlocatortocontaintexttext-options)
|
||||
- [`expect(locator).toHaveAttribute(name, value)`](./test-assertions#expectlocatortohaveattributename-value)
|
||||
- [`expect(locator).toHaveClass(expected)`](./test-assertions#expectlocatortohaveclassexpected)
|
||||
- [`expect(locator).toHaveCount(count)`](./test-assertions#expectlocatortohavecountcount)
|
||||
- [`expect(locator).toHaveCSS(name, value)`](./test-assertions#expectlocatortohavecssname-value)
|
||||
- [`expect(locator).toHaveId(id)`](./test-assertions#expectlocatortohaveidid)
|
||||
- [`expect(locator).toHaveJSProperty(name, value)`](./test-assertions#expectlocatortohavejspropertyname-value)
|
||||
- [`expect(locator).toHaveText(expected, options)`](./test-assertions#expectlocatortohavetextexpected-options)
|
||||
- [`expect(page).toHaveTitle(title)`](./test-assertions#expectpagetohavetitletitle)
|
||||
- [`expect(page).toHaveURL(url)`](./test-assertions#expectpagetohaveurlurl)
|
||||
- [`expect(locator).toHaveValue(value)`](./test-assertions#expectlocatortohavevaluevalue)
|
||||
- [`expect(locator).toBeChecked()`](./api/class-locatorassertions#locator-assertions-to-be-checked)
|
||||
- [`expect(locator).toBeDisabled()`](./api/class-locatorassertions#locator-assertions-to-be-disabled)
|
||||
- [`expect(locator).toBeEditable()`](./api/class-locatorassertions#locator-assertions-to-be-editable)
|
||||
- [`expect(locator).toBeEmpty()`](./api/class-locatorassertions#locator-assertions-to-be-empty)
|
||||
- [`expect(locator).toBeEnabled()`](./api/class-locatorassertions#locator-assertions-to-be-enabled)
|
||||
- [`expect(locator).toBeFocused()`](./api/class-locatorassertions#locator-assertions-to-be-focused)
|
||||
- [`expect(locator).toBeHidden()`](./api/class-locatorassertions#locator-assertions-to-be-hidden)
|
||||
- [`expect(locator).toBeVisible()`](./api/class-locatorassertions#locator-assertions-to-be-visible)
|
||||
- [`expect(locator).toContainText(text, options?)`](./api/class-locatorassertions#locator-assertions-to-contain-text)
|
||||
- [`expect(locator).toHaveAttribute(name, value)`](./api/class-locatorassertions#locator-assertions-to-have-attribute)
|
||||
- [`expect(locator).toHaveClass(expected)`](./api/class-locatorassertions#locator-assertions-to-have-class)
|
||||
- [`expect(locator).toHaveCount(count)`](./api/class-locatorassertions#locator-assertions-to-have-count)
|
||||
- [`expect(locator).toHaveCSS(name, value)`](./api/class-locatorassertions#locator-assertions-to-have-css)
|
||||
- [`expect(locator).toHaveId(id)`](./api/class-locatorassertions#locator-assertions-to-have-id)
|
||||
- [`expect(locator).toHaveJSProperty(name, value)`](./api/class-locatorassertions#locator-assertions-to-have-js-property)
|
||||
- [`expect(locator).toHaveText(expected, options)`](./api/class-locatorassertions#locator-assertions-to-have-text)
|
||||
- [`expect(page).toHaveTitle(title)`](./api/class-pageassertions#page-assertions-to-have-title)
|
||||
- [`expect(page).toHaveURL(url)`](./api/class-pageassertions#page-assertions-to-have-url)
|
||||
- [`expect(locator).toHaveValue(value)`](./api/class-locatorassertions#locator-assertions-to-have-value)
|
||||
|
||||
#### ⛓ Serial mode with [`describe.serial`](./api/class-test#test-describe-serial)
|
||||
|
||||
@ -2243,7 +2243,7 @@ Step information is exposed in reporters API.
|
||||
|
||||
#### 🌎 Launch web server before running tests
|
||||
|
||||
To launch a server during the tests, use the [`webServer`](./test-webserver) option in the configuration file. The server will wait for a given url to be available before running the tests, and the url will be passed over to Playwright as a [`baseURL`](./api/class-fixtures#fixtures-base-url) when creating a context.
|
||||
To launch a server during the tests, use the [`webServer`](./test-webserver) option in the configuration file. The server will wait for a given url to be available before running the tests, and the url will be passed over to Playwright as a [`baseURL`](./api/class-testoptions#test-options-base-url) when creating a context.
|
||||
|
||||
```ts title="playwright.config.ts"
|
||||
import { defineConfig } from '@playwright/test';
|
||||
@ -2272,7 +2272,7 @@ Learn more in the [documentation](./test-webserver).
|
||||
#### Playwright Test
|
||||
|
||||
- **⚡️ Introducing [Reporter API](https://github.com/microsoft/playwright/blob/65a9037461ffc15d70cdc2055832a0c5512b227c/packages/playwright-test/types/testReporter.d.ts)** which is already used to create an [Allure Playwright reporter](https://github.com/allure-framework/allure-js/pull/297).
|
||||
- **⛺️ New [`baseURL` fixture](./test-configuration#basic-options)** to support relative paths in tests.
|
||||
- **⛺️ New [`baseURL` fixture](./test-configuration#basic-configuration)** to support relative paths in tests.
|
||||
|
||||
|
||||
#### Playwright
|
||||
|
||||
@ -89,7 +89,7 @@ If your custom reporter does not print anything to the terminal, implement [`met
|
||||
|
||||
**Merged report API notes**
|
||||
|
||||
When merging mutliple [`blob`](./test-reporters#blob-reporter) reports via [`merge-reports`](./test-sharding#merge-reports-cli) CLI
|
||||
When merging multiple [`blob`](../test-reporters#blob-reporter) reports via [`merge-reports`](../test-sharding#merge-reports-cli) CLI
|
||||
command, the same [Reporter] API is called to produce final reports and all existing reporters
|
||||
should work without any changes. There some subtle differences though which might affect some custom
|
||||
reporters.
|
||||
|
||||
@ -99,7 +99,7 @@ await expect(page.getByText('the lion king')).toBeVisible();
|
||||
await expect(page.getByText('the mummy')).toBeHidden();
|
||||
```
|
||||
|
||||
When you cannot find a suitable assertion, use [`expect.poll`](./test-assertions#polling) instead.
|
||||
When you cannot find a suitable assertion, use [`expect.poll`](./test-assertions#expectpoll) instead.
|
||||
|
||||
```js
|
||||
await expect.poll(async () => {
|
||||
|
||||
@ -22,7 +22,7 @@ Playwright Trace Viewer is a GUI tool that lets you explore recorded Playwright
|
||||
|
||||
## Recording a Trace
|
||||
|
||||
By default the [playwright.config](/test-configuration.md#record-test-trace) file will contain the configuration needed to create a `trace.zip` file for each test. Traces are setup to run `on-first-retry` meaning they will be run on the first retry of a failed test. Also `retries` are set to 2 when running on CI and 0 locally. This means the traces will be recorded on the first retry of a failed test but not on the first run and not on the second retry.
|
||||
By default the [playwright.config](./trace-viewer.md#recording-a-trace-on-ci) file will contain the configuration needed to create a `trace.zip` file for each test. Traces are setup to run `on-first-retry` meaning they will be run on the first retry of a failed test. Also `retries` are set to 2 when running on CI and 0 locally. This means the traces will be recorded on the first retry of a failed test but not on the first run and not on the second retry.
|
||||
|
||||
```js title="playwright.config.ts"
|
||||
import { defineConfig } from '@playwright/test';
|
||||
|
||||
4
packages/playwright/types/testReporter.d.ts
vendored
4
packages/playwright/types/testReporter.d.ts
vendored
@ -336,8 +336,8 @@ export interface FullResult {
|
||||
*
|
||||
* **Merged report API notes**
|
||||
*
|
||||
* When merging mutliple [`blob`](https://playwright.dev/docs/api/test-reporters#blob-reporter) reports via
|
||||
* [`merge-reports`](https://playwright.dev/docs/api/test-sharding#merge-reports-cli) CLI command, the same {@link Reporter} API is called to
|
||||
* When merging multiple [`blob`](https://playwright.dev/docs/test-reporters#blob-reporter) reports via
|
||||
* [`merge-reports`](https://playwright.dev/docs/test-sharding#merge-reports-cli) CLI command, the same {@link Reporter} API is called to
|
||||
* produce final reports and all existing reporters should work without any changes. There some subtle differences
|
||||
* though which might affect some custom reporters.
|
||||
* - Projects from different shards are always kept as separate {@link TestProject} objects. E.g. if project
|
||||
|
||||
@ -133,14 +133,14 @@ async function run() {
|
||||
for (const lang of langs) {
|
||||
try {
|
||||
let documentation = parseApi(path.join(documentationRoot, 'api'));
|
||||
documentation.filterForLanguage(lang);
|
||||
if (lang === 'js') {
|
||||
const testDocumentation = parseApi(path.join(documentationRoot, 'test-api'), path.join(documentationRoot, 'api', 'params.md'));
|
||||
testDocumentation.filterForLanguage('js');
|
||||
const testReporterDocumentation = parseApi(path.join(documentationRoot, 'test-reporter-api'));
|
||||
testReporterDocumentation.filterForLanguage('js');
|
||||
documentation = documentation.mergeWith(testDocumentation).mergeWith(testReporterDocumentation);
|
||||
documentation = documentation.mergeWith(
|
||||
parseApi(path.join(documentationRoot, 'test-api'), path.join(documentationRoot, 'api', 'params.md'))
|
||||
).mergeWith(
|
||||
parseApi(path.join(documentationRoot, 'test-reporter-api'))
|
||||
);
|
||||
}
|
||||
documentation.filterForLanguage(lang);
|
||||
|
||||
// This validates member links.
|
||||
documentation.setLinkRenderer(() => undefined);
|
||||
@ -153,8 +153,18 @@ async function run() {
|
||||
|
||||
for (const cls of documentation.classesArray) {
|
||||
const filePath = path.join(documentationRoot, 'api', 'class-' + cls.name.toLowerCase() + '.md');
|
||||
for (const member of cls.membersArray)
|
||||
mdSections.add(filePath + '#' + toKebabCase(cls.name).toLowerCase() + '-' + toKebabCase(member.name).toLowerCase());
|
||||
for (const member of cls.membersArray) {
|
||||
const memberHash = filePath + '#' + toKebabCase(cls.name).toLowerCase() + '-' + toKebabCase(member.name).toLowerCase()
|
||||
mdSections.add(memberHash);
|
||||
for (const arg of member.argsArray) {
|
||||
mdSections.add(memberHash + '-option-' + toKebabCase(arg.name).toLowerCase());
|
||||
if (arg.name === "options" && arg.type) {
|
||||
for (const option of arg.type.deepProperties())
|
||||
mdSections.add(memberHash + '-option-' + toKebabCase(option.name).toLowerCase());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const event of cls.eventsArray)
|
||||
mdSections.add(filePath + '#' + toKebabCase(cls.name).toLowerCase() + '-event-' + toKebabCase(event.name).toLowerCase());
|
||||
}
|
||||
@ -211,7 +221,8 @@ async function run() {
|
||||
}
|
||||
if (!node.text)
|
||||
return;
|
||||
for (const [, mdLinkName, mdLink] of node.text.matchAll(/\[([\w\s\d]+)\]\((.*?)\)/g)) {
|
||||
// Match links in a lax way (.+), so they can include spaces, backticks etc.
|
||||
for (const [, mdLinkName, mdLink] of node.text.matchAll(/\[(.+)\]\((.*?)\)/g)) {
|
||||
const isExternal = mdLink.startsWith('http://') || mdLink.startsWith('https://');
|
||||
if (isExternal)
|
||||
continue;
|
||||
@ -296,6 +307,10 @@ async function getBrowserVersions() {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} text
|
||||
* @returns {string}
|
||||
*/
|
||||
function mdSectionHash(text) {
|
||||
return text.toLowerCase().replace(/\s/g, '-').replace(/[^-_a-z0-9]/g, '').replace(/^-+/, '');
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user