diff --git a/docs/src/release-notes-js.md b/docs/src/release-notes-js.md index 000c773971fcc..48911bf35a67b 100644 --- a/docs/src/release-notes-js.md +++ b/docs/src/release-notes-js.md @@ -52,7 +52,7 @@ If you include a named capture group into the expression, then Playwright will p ```js import { test, expect } from '@playwright/test'; -test.use({ baseUrl: `http://localhost:${process.env.MY_SERVER_PORT ?? 3000}` }); +test.use({ baseURL: `http://localhost:${process.env.MY_SERVER_PORT ?? 3000}` }); test('homepage', async ({ page }) => { await page.goto('/'); diff --git a/examples/todomvc/tests/md/adding-todos.spec.md b/examples/todomvc/tests/md/adding-todos.spec.md new file mode 100644 index 0000000000000..d8aa804fc5d98 --- /dev/null +++ b/examples/todomvc/tests/md/adding-todos.spec.md @@ -0,0 +1,32 @@ +## Adding Todos + +- seed: ./seed.spec.md + +### should add single todo + +- tag: @one @two +- tag: @three +- annotation: link=https://playwright.dev +- annotation: link2=https://demo.playwright.dev + +* Type 'Buy groceries' into the input field +* expect: The text appears in the input field +- Press Enter to submit the todo +- group: Verify todo is added to the list + - expect: The new todo 'Buy groceries' appears in the todo list + - expect: The input field is cleared + - expect: The todo counter shows '1 item left' + +### should add multiple todos + +1. Add first todo 'Buy milk' + - expect: The todo appears in the list + - expect: Counter shows '1 item left' +2. Add second todo 'Walk the dog' + - expect: Both todos appear in the list + - expect: Counter shows '2 items left' +3. // this is a comment +4. Add third todo 'Finish report' + - expect: All three todos appear in the list + - // this is a comment + - expect: Counter shows '3 items left' diff --git a/examples/todomvc/tests/md/adding-todos.spec.md-cache.json b/examples/todomvc/tests/md/adding-todos.spec.md-cache.json new file mode 100644 index 0000000000000..c2cc9b18a0cb7 --- /dev/null +++ b/examples/todomvc/tests/md/adding-todos.spec.md-cache.json @@ -0,0 +1,160 @@ +{ + "page title contains \"TodoMVC\"": { + "actions": [] + }, + "Press Enter to submit the todo": { + "actions": [ + { + "method": "pressKey", + "key": "Enter", + "code": "await page.keyboard.press('Enter');" + } + ] + }, + "The input field 'What needs to be done?' is visible": { + "actions": [ + { + "method": "expectVisible", + "selector": "internal:role=textbox[name=\"What needs to be done?\"i]", + "code": "await expect(page.getByRole('textbox', { name: 'What needs to be done?' })).toBeVisible();" + } + ] + }, + "The input field is cleared": { + "actions": [ + { + "method": "expectValue", + "selector": "internal:role=textbox[name=\"What needs to be done?\"i]", + "type": "textbox", + "value": "", + "code": "await expect(page.getByRole('textbox', { name: 'What needs to be done?' })).toHaveValue('');" + } + ] + }, + "The new todo 'Buy groceries' appears in the todo list": { + "actions": [ + { + "method": "expectVisible", + "selector": "internal:text=\"Buy groceries\"i", + "code": "await expect(page.getByText('Buy groceries')).toBeVisible();" + } + ] + }, + "The text appears in the input field": { + "actions": [ + { + "method": "expectValue", + "selector": "internal:role=textbox[name=\"What needs to be done?\"i]", + "type": "textbox", + "value": "Buy groceries", + "code": "await expect(page.getByRole('textbox', { name: 'What needs to be done?' })).toHaveValue('Buy groceries');" + } + ] + }, + "The todo counter shows '1 item left'": { + "actions": [ + { + "method": "expectVisible", + "selector": "internal:text=\"1 item left\"i", + "code": "await expect(page.getByText('1 item left')).toBeVisible();" + } + ] + }, + "Type 'Buy groceries' into the input field": { + "actions": [ + { + "method": "fill", + "selector": "internal:role=textbox[name=\"What needs to be done?\"i]", + "text": "Buy groceries", + "code": "await page.getByRole('textbox', { name: 'What needs to be done?' }).fill('Buy groceries');" + } + ] + }, + "Add first todo 'Buy milk'": { + "actions": [ + { + "method": "fill", + "selector": "internal:role=textbox[name=\"What needs to be done?\"i]", + "text": "Buy milk", + "submit": true, + "code": "await page.getByRole('textbox', { name: 'What needs to be done?' }).fill('Buy milk');\nawait page.keyboard.press('Enter');" + } + ] + }, + "Add second todo 'Walk the dog'": { + "actions": [ + { + "method": "fill", + "selector": "internal:role=textbox[name=\"What needs to be done?\"i]", + "text": "Walk the dog", + "submit": true, + "code": "await page.getByRole('textbox', { name: 'What needs to be done?' }).fill('Walk the dog');\nawait page.keyboard.press('Enter');" + } + ] + }, + "Add third todo 'Finish report'": { + "actions": [ + { + "method": "fill", + "selector": "internal:role=textbox[name=\"What needs to be done?\"i]", + "text": "Finish report", + "submit": true, + "code": "await page.getByRole('textbox', { name: 'What needs to be done?' }).fill('Finish report');\nawait page.keyboard.press('Enter');" + } + ] + }, + "All three todos appear in the list": { + "actions": [ + { + "method": "expectAria", + "template": "- list:\n - listitem: Buy milk\n - listitem: Walk the dog\n - listitem: Finish report", + "code": "await expect(page.locator('body')).toMatchAria(`\n- list:\n - listitem: Buy milk\n - listitem: Walk the dog\n - listitem: Finish report\n`);" + } + ] + }, + "Both todos appear in the list": { + "actions": [ + { + "method": "expectAria", + "template": "- list:\n - listitem: Buy milk\n - listitem: Walk the dog", + "code": "await expect(page.locator('body')).toMatchAria(`\n- list:\n - listitem: Buy milk\n - listitem: Walk the dog\n`);" + } + ] + }, + "Counter shows '1 item left'": { + "actions": [ + { + "method": "expectVisible", + "selector": "internal:text=\"1 item left\"i", + "code": "await expect(page.getByText('1 item left')).toBeVisible();" + } + ] + }, + "Counter shows '2 items left'": { + "actions": [ + { + "method": "expectVisible", + "selector": "internal:text=\"2 items left\"i", + "code": "await expect(page.getByText('2 items left')).toBeVisible();" + } + ] + }, + "Counter shows '3 items left'": { + "actions": [ + { + "method": "expectVisible", + "selector": "internal:text=\"3 items left\"i", + "code": "await expect(page.getByText('3 items left')).toBeVisible();" + } + ] + }, + "The todo appears in the list": { + "actions": [ + { + "method": "expectVisible", + "selector": "internal:text=\"Buy milk\"i", + "code": "await expect(page.getByText('Buy milk')).toBeVisible();" + } + ] + } +} \ No newline at end of file diff --git a/examples/todomvc/tests/md/seed.spec.md b/examples/todomvc/tests/md/seed.spec.md new file mode 100644 index 0000000000000..60b2be1c674f7 --- /dev/null +++ b/examples/todomvc/tests/md/seed.spec.md @@ -0,0 +1,14 @@ +## Seed + +- fixtures: ../fixtures + +### seed test + +- Navigate to 'https://demo.playwright.dev/todomvc' + ```ts + await page.goto('https://demo.playwright.dev/todomvc'); + ``` + +- expect: page title contains "TodoMVC" + +- expect: The input field 'What needs to be done?' is visible diff --git a/examples/todomvc/tests/md/seed.spec.md-cache.json b/examples/todomvc/tests/md/seed.spec.md-cache.json new file mode 100644 index 0000000000000..333dfbf16d630 --- /dev/null +++ b/examples/todomvc/tests/md/seed.spec.md-cache.json @@ -0,0 +1,14 @@ +{ + "page title contains \"TodoMVC\"": { + "actions": [] + }, + "The input field 'What needs to be done?' is visible": { + "actions": [ + { + "method": "expectVisible", + "selector": "internal:role=textbox[name=\"What needs to be done?\"i]", + "code": "await expect(page.getByRole('textbox', { name: 'What needs to be done?' })).toBeVisible();" + } + ] + } +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 828a03cdba7e9..4ee02fc2e2172 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,12 +18,13 @@ "@eslint/compat": "^1.3.2", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "^9.34.0", - "@lowire/loop": "^0.0.15", + "@lowire/loop": "^0.0.18", "@modelcontextprotocol/sdk": "^1.17.5", "@octokit/graphql-schema": "^15.26.0", "@stylistic/eslint-plugin": "^5.2.3", "@types/codemirror": "^5.60.7", "@types/formidable": "^2.0.4", + "@types/mdast": "^4.0.4", "@types/node": "18.19.76", "@types/react": "^19.2.1", "@types/react-dom": "^19.2.1", @@ -1064,9 +1065,9 @@ } }, "node_modules/@lowire/loop": { - "version": "0.0.15", - "resolved": "https://registry.npmjs.org/@lowire/loop/-/loop-0.0.15.tgz", - "integrity": "sha512-XycNy4hSRgfb54NHPf/TIRTC+UGpvZMg6z3T3IRgTprj/nUoW5/XKCR3a3dCO4RC88n8ARiTjgEtFfoJfH9S8w==", + "version": "0.0.18", + "resolved": "https://registry.npmjs.org/@lowire/loop/-/loop-0.0.18.tgz", + "integrity": "sha512-ZusERFapOfczMai18jPV516lLOpC2Vu0yqOHIJ4W0gewfQ9T8VRgKQeX65NPrKAhVuxPtCJ2tvnW9I1bU3aBuA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -1810,6 +1811,16 @@ "@types/node": "*" } }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/@types/node": { "version": "18.19.76", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.76.tgz", @@ -1857,6 +1868,13 @@ "@types/estree": "*" } }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/ws": { "version": "8.18.1", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", diff --git a/package.json b/package.json index f4fa02b71f5e5..a5fbc8cf419c7 100644 --- a/package.json +++ b/package.json @@ -55,12 +55,13 @@ "@eslint/compat": "^1.3.2", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "^9.34.0", - "@lowire/loop": "^0.0.15", + "@lowire/loop": "^0.0.18", "@modelcontextprotocol/sdk": "^1.17.5", "@octokit/graphql-schema": "^15.26.0", "@stylistic/eslint-plugin": "^5.2.3", "@types/codemirror": "^5.60.7", "@types/formidable": "^2.0.4", + "@types/mdast": "^4.0.4", "@types/node": "18.19.76", "@types/react": "^19.2.1", "@types/react-dom": "^19.2.1", diff --git a/packages/playwright-core/ThirdPartyNotices.txt b/packages/playwright-core/ThirdPartyNotices.txt index 132673492a51d..97c06433bbd63 100644 --- a/packages/playwright-core/ThirdPartyNotices.txt +++ b/packages/playwright-core/ThirdPartyNotices.txt @@ -4,7 +4,7 @@ THIRD-PARTY SOFTWARE NOTICES AND INFORMATION This project incorporates components from the projects listed below. The original copyright notices and the licenses under which Microsoft received such components are set forth below. Microsoft reserves all rights not expressly granted herein, whether by implication, estoppel or otherwise. -- @lowire/loop@0.0.15 (https://github.com/pavelfeldman/lowire) +- @lowire/loop@0.0.18 (https://github.com/pavelfeldman/lowire) - @modelcontextprotocol/sdk@1.24.2 (https://github.com/modelcontextprotocol/typescript-sdk) - accepts@2.0.0 (https://github.com/jshttp/accepts) - agent-base@7.1.4 (https://github.com/TooTallNate/proxy-agents) @@ -135,7 +135,7 @@ This project incorporates components from the projects listed below. The origina - zod-to-json-schema@3.25.0 (https://github.com/StefanTerdell/zod-to-json-schema) - zod@3.25.76 (https://github.com/colinhacks/zod) -%% @lowire/loop@0.0.15 NOTICES AND INFORMATION BEGIN HERE +%% @lowire/loop@0.0.18 NOTICES AND INFORMATION BEGIN HERE ========================================= Apache License Version 2.0, January 2004 @@ -339,7 +339,7 @@ Apache License See the License for the specific language governing permissions and limitations under the License. ========================================= -END OF @lowire/loop@0.0.15 AND INFORMATION +END OF @lowire/loop@0.0.18 AND INFORMATION %% @modelcontextprotocol/sdk@1.24.2 NOTICES AND INFORMATION BEGIN HERE ========================================= diff --git a/packages/playwright-core/browsers.json b/packages/playwright-core/browsers.json index 33d683d9d2fb2..a184cda1e544f 100644 --- a/packages/playwright-core/browsers.json +++ b/packages/playwright-core/browsers.json @@ -45,7 +45,7 @@ }, { "name": "webkit", - "revision": "2242", + "revision": "2245", "installByDefault": true, "revisionOverrides": { "debian11-x64": "2105", diff --git a/packages/playwright-core/bundles/mcp/package-lock.json b/packages/playwright-core/bundles/mcp/package-lock.json index 10c5a8d6b6e57..5adb3518e15fc 100644 --- a/packages/playwright-core/bundles/mcp/package-lock.json +++ b/packages/playwright-core/bundles/mcp/package-lock.json @@ -8,16 +8,16 @@ "name": "mcp-bundle", "version": "0.0.1", "dependencies": { - "@lowire/loop": "^0.0.15", + "@lowire/loop": "^0.0.18", "@modelcontextprotocol/sdk": "^1.24.0", "zod": "^3.25.76", "zod-to-json-schema": "^3.24.6" } }, "node_modules/@lowire/loop": { - "version": "0.0.15", - "resolved": "https://registry.npmjs.org/@lowire/loop/-/loop-0.0.15.tgz", - "integrity": "sha512-XycNy4hSRgfb54NHPf/TIRTC+UGpvZMg6z3T3IRgTprj/nUoW5/XKCR3a3dCO4RC88n8ARiTjgEtFfoJfH9S8w==", + "version": "0.0.18", + "resolved": "https://registry.npmjs.org/@lowire/loop/-/loop-0.0.18.tgz", + "integrity": "sha512-ZusERFapOfczMai18jPV516lLOpC2Vu0yqOHIJ4W0gewfQ9T8VRgKQeX65NPrKAhVuxPtCJ2tvnW9I1bU3aBuA==", "license": "Apache-2.0", "engines": { "node": ">=20" diff --git a/packages/playwright-core/bundles/mcp/package.json b/packages/playwright-core/bundles/mcp/package.json index b386ca3240117..ab0c970c5d6ca 100644 --- a/packages/playwright-core/bundles/mcp/package.json +++ b/packages/playwright-core/bundles/mcp/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "dependencies": { - "@lowire/loop": "^0.0.15", + "@lowire/loop": "^0.0.18", "@modelcontextprotocol/sdk": "^1.24.0", "zod": "^3.25.76", "zod-to-json-schema": "^3.24.6" diff --git a/packages/playwright-core/src/server/agent/actionRunner.ts b/packages/playwright-core/src/server/agent/actionRunner.ts index af2994edac467..1244fae2d7a54 100644 --- a/packages/playwright-core/src/server/agent/actionRunner.ts +++ b/packages/playwright-core/src/server/agent/actionRunner.ts @@ -18,6 +18,7 @@ import { serializeExpectedTextValues } from '../utils/expectUtils'; import { monotonicTime } from '../../utils/isomorphic/time'; import { createGuid } from '../utils/crypto'; import { parseAriaSnapshotUnsafe } from '../../utils/isomorphic/ariaSnapshot'; +import { renderTitleForCall } from '../../utils/isomorphic/protocolFormatter'; import { ProgressController } from '../progress'; import { yaml } from '../../utilsBundle'; import { serializeError } from '../errors'; @@ -172,7 +173,7 @@ export function performActionTimeout(action: actions.Action): number { } } -export function traceParamsForAction(action: actions.Action): { method: string, title: string, params: any } { +export function traceParamsForAction(action: actions.Action): { title?: string, type: string, method: string, params: any } { const timeout = generateActionTimeout(action); switch (action.method) { case 'navigate': { @@ -180,7 +181,7 @@ export function traceParamsForAction(action: actions.Action): { method: string, url: action.url, timeout, }; - return { method: 'goto', title: 'Navigate', params }; + return { type: 'Frame', method: 'goto', params }; } case 'click': { const params: channels.FrameClickParams = { @@ -191,7 +192,7 @@ export function traceParamsForAction(action: actions.Action): { method: string, clickCount: action.clickCount, timeout, }; - return { method: 'click', title: 'Click', params }; + return { type: 'Frame', method: 'click', params }; } case 'drag': { const params: channels.FrameDragAndDropParams = { @@ -199,7 +200,7 @@ export function traceParamsForAction(action: actions.Action): { method: string, target: action.targetSelector, timeout, }; - return { method: 'dragAndDrop', title: 'Drag and Drop', params }; + return { type: 'Frame', method: 'dragAndDrop', params }; } case 'hover': { const params: channels.FrameHoverParams = { @@ -207,13 +208,13 @@ export function traceParamsForAction(action: actions.Action): { method: string, modifiers: action.modifiers, timeout, }; - return { method: 'hover', title: 'Hover', params }; + return { type: 'Frame', method: 'hover', params }; } case 'pressKey': { const params: channels.PageKeyboardPressParams = { key: action.key, }; - return { method: 'press', title: 'Press', params }; + return { type: 'Page', method: 'keyboardPress', params }; } case 'pressSequentially': { const params: channels.FrameTypeParams = { @@ -221,7 +222,7 @@ export function traceParamsForAction(action: actions.Action): { method: string, text: action.text, timeout, }; - return { method: 'type', title: 'Type', params }; + return { type: 'Frame', method: 'type', params }; } case 'fill': { const params: channels.FrameFillParams = { @@ -230,7 +231,7 @@ export function traceParamsForAction(action: actions.Action): { method: string, value: action.text, timeout, }; - return { method: 'fill', title: 'Fill', params }; + return { type: 'Frame', method: 'fill', params }; } case 'setChecked': { if (action.checked) { @@ -239,14 +240,14 @@ export function traceParamsForAction(action: actions.Action): { method: string, strict: true, timeout, }; - return { method: 'check', title: 'Check', params }; + return { type: 'Frame', method: 'check', params }; } else { const params: channels.FrameUncheckParams = { selector: action.selector, strict: true, timeout, }; - return { method: 'uncheck', title: 'Uncheck', params }; + return { type: 'Frame', method: 'uncheck', params }; } } case 'selectOption': { @@ -256,7 +257,7 @@ export function traceParamsForAction(action: actions.Action): { method: string, options: action.labels.map(label => ({ label })), timeout, }; - return { method: 'selectOption', title: 'Select Option', params }; + return { type: 'Frame', method: 'selectOption', params }; } case 'expectValue': { if (action.type === 'textbox' || action.type === 'combobox' || action.type === 'slider') { @@ -268,7 +269,7 @@ export function traceParamsForAction(action: actions.Action): { method: string, isNot: !!action.isNot, timeout: kDefaultTimeout, }; - return { method: 'expect', title: 'Expect Value', params }; + return { type: 'Frame', method: 'expect', title: 'Expect Value', params }; } else if (action.type === 'checkbox' || action.type === 'radio') { // TODO: provide serialized expected value const params: channels.FrameExpectParams = { @@ -277,7 +278,7 @@ export function traceParamsForAction(action: actions.Action): { method: string, isNot: !!action.isNot, timeout: kDefaultTimeout, }; - return { method: 'expect', title: 'Expect Checked', params }; + return { type: 'Frame', method: 'expect', title: 'Expect Checked', params }; } else { throw new Error(`Unsupported element type: ${action.type}`); } @@ -289,7 +290,7 @@ export function traceParamsForAction(action: actions.Action): { method: string, isNot: !!action.isNot, timeout: kDefaultTimeout, }; - return { method: 'expect', title: 'Expect Visible', params }; + return { type: 'Frame', method: 'expect', title: 'Expect Visible', params }; } case 'expectAria': { // TODO: provide serialized expected value @@ -300,13 +301,14 @@ export function traceParamsForAction(action: actions.Action): { method: string, isNot: !!action.isNot, timeout: kDefaultTimeout, }; - return { method: 'expect', title: 'Expect Aria Snapshot', params }; + return { type: 'Frame', method: 'expect', title: 'Expect Aria Snapshot', params }; } } } function callMetadataForAction(frame: Frame, action: actions.Action): CallMetadata { - const { method, title, params } = traceParamsForAction(action); + const traceParams = traceParamsForAction(action); + const title = renderTitleForCall(traceParams); const callMetadata: CallMetadata = { id: `call@${createGuid()}`, @@ -316,8 +318,8 @@ function callMetadataForAction(frame: Frame, action: actions.Action): CallMetada startTime: monotonicTime(), endTime: 0, type: 'Frame', - method, - params, + method: traceParams.method, + params: traceParams.params, title, log: [], }; diff --git a/packages/playwright-core/src/server/agent/pageAgent.ts b/packages/playwright-core/src/server/agent/pageAgent.ts index 4b8425c74f4bf..be64e92b00dde 100644 --- a/packages/playwright-core/src/server/agent/pageAgent.ts +++ b/packages/playwright-core/src/server/agent/pageAgent.ts @@ -67,6 +67,7 @@ export async function pageAgentExpect(progress: Progress, context: Context, expe ${expectation} `; + callParams.maxTurns = callParams.maxTurns ?? 3; await runLoop(progress, context, expectTools, task, undefined, callParams); await updateCache(context, cacheKey); } @@ -94,6 +95,7 @@ async function runLoop(progress: Progress, context: Context, toolDefinitions: To const { full } = await page.snapshotForAI(progress); const { tools, callTool, reportedResult } = toolsForLoop(progress, context, toolDefinitions, { resultSchema }); + const secrets = Object.fromEntries((context.agentParams.secrets || [])?.map(s => ([s.name, s.value]))); const loop = new Loop({ api: context.agentParams.api as any, @@ -106,6 +108,7 @@ async function runLoop(progress: Progress, context: Context, toolDefinitions: To debug, callTool, tools, + secrets, ...context.events, }); diff --git a/packages/playwright-core/src/server/webkit/protocol.d.ts b/packages/playwright-core/src/server/webkit/protocol.d.ts index fbc2055e569e1..d56e9947aab79 100644 --- a/packages/playwright-core/src/server/webkit/protocol.d.ts +++ b/packages/playwright-core/src/server/webkit/protocol.d.ts @@ -2076,6 +2076,10 @@ export namespace Protocol { * Show labels for grid area names. If not specified, the default value is false. */ showAreaNames?: boolean; + /** + * Show labels for grid item order. If not specified, the default value is false. + */ + showOrderNumbers?: boolean; } /** * Configuration data for flex overlays. @@ -2175,8 +2179,7 @@ export namespace Protocol { * The native width of the video track in CSS pixels */ width: number; - spatialVideoMetadata?: SpatialVideoMetadata; - videoProjectionMetadata?: VideoProjectionMetadata; + immersiveVideoMetadata?: ImmersiveVideoMetadata; /** * Whether the track contains protected contents */ @@ -2223,35 +2226,30 @@ export namespace Protocol { /** * A structure containing metadata describing spatial video properties. */ - export interface SpatialVideoMetadata { + export interface ImmersiveVideoMetadata { + /** + * The kind of immersive video. + */ + kind: VideoProjectionMetadataKind; width: number; height: number; /** * The horizontal field-of-view measurement, in degrees */ - horizontalFOVDegrees: number; + horizontalFieldOfView?: number; /** * The distance between the centers of the lenses in a camera system, in micrometers */ - baseline: number; + stereoCameraBaseline?: number; /** - * The relative shift of the left and right eye images, as a percentage. + * The relative shift of the left and right eye images, as a percentage */ - disparityAdjustment: number; + horizontalDisparityAdjustment?: number; } /** * Video Projection Metadata Kind. */ - export type VideoProjectionMetadataKind = "unknown"|"equirectangular"|"half-equirectangular"|"equi-angular-cubemap"|"parametric"|"pyramid"|"apple-immersive-video"; - /** - * A structure containing metadata describing video projections. - */ - export interface VideoProjectionMetadata { - /** - * The kind of video projection. - */ - kind: VideoProjectionMetadataKind; - } + export type VideoProjectionMetadataKind = "unknown"|"rectilinear"|"equirectangular"|"half-equirectangular"|"equi-angular-cubemap"|"parametric"|"pyramid"|"apple-immersive-video"; export interface ViewportSize { width: number; height: number; @@ -5334,6 +5332,21 @@ the top of the viewport and Y increases as it proceeds towards the bottom of the */ compositingReasons: CompositingReasons; } + /** + * Captures a snapshot of the layer's rendered content as a PNG data URL. + */ + export type requestContentParameters = { + /** + * The id of the layer to snapshot. + */ + layerId: LayerId; + } + export type requestContentReturnValue = { + /** + * Base64-encoded PNG data URL of the layer's rendered content. + */ + content: string; + } } /** @@ -9343,6 +9356,7 @@ the top of the viewport and Y increases as it proceeds towards the bottom of the "LayerTree.disable": LayerTree.disableParameters; "LayerTree.layersForNode": LayerTree.layersForNodeParameters; "LayerTree.reasonsForCompositingLayer": LayerTree.reasonsForCompositingLayerParameters; + "LayerTree.requestContent": LayerTree.requestContentParameters; "Memory.enable": Memory.enableParameters; "Memory.disable": Memory.disableParameters; "Memory.startTracking": Memory.startTrackingParameters; @@ -9646,6 +9660,7 @@ the top of the viewport and Y increases as it proceeds towards the bottom of the "LayerTree.disable": LayerTree.disableReturnValue; "LayerTree.layersForNode": LayerTree.layersForNodeReturnValue; "LayerTree.reasonsForCompositingLayer": LayerTree.reasonsForCompositingLayerReturnValue; + "LayerTree.requestContent": LayerTree.requestContentReturnValue; "Memory.enable": Memory.enableReturnValue; "Memory.disable": Memory.disableReturnValue; "Memory.startTracking": Memory.startTrackingReturnValue; diff --git a/packages/playwright-core/src/server/webkit/wkPage.ts b/packages/playwright-core/src/server/webkit/wkPage.ts index 6220d32518b34..0bdb92c031185 100644 --- a/packages/playwright-core/src/server/webkit/wkPage.ts +++ b/packages/playwright-core/src/server/webkit/wkPage.ts @@ -46,7 +46,7 @@ import type * as types from '../types'; const UTILITY_WORLD_NAME = '__playwright_utility_world__'; -const enableFrameSessions = !!process.env.WK_ENABLE_FRAME_SESSIONS; +const enableFrameSessions = !process.env.WK_DISABLE_FRAME_SESSIONS; export class WKPage implements PageDelegate { readonly rawMouse: RawMouseImpl; diff --git a/packages/playwright-core/src/utils/isomorphic/trace/traceModel.ts b/packages/playwright-core/src/utils/isomorphic/trace/traceModel.ts index 8358018715774..afa2e7d63e6e6 100644 --- a/packages/playwright-core/src/utils/isomorphic/trace/traceModel.ts +++ b/packages/playwright-core/src/utils/isomorphic/trace/traceModel.ts @@ -355,6 +355,15 @@ export function buildActionTree(actions: ActionTraceEventInContext[]): { rootIte parent.children.push(item); item.parent = parent; } + + const inheritStack = (item: ActionTreeItem) => { + for (const child of item.children) { + child.action.stack = child.action.stack ?? item.action.stack; + inheritStack(child); + } + }; + inheritStack(rootItem); + return { rootItem, itemMap }; } diff --git a/packages/playwright/ThirdPartyNotices.txt b/packages/playwright/ThirdPartyNotices.txt index e56f64221f2e0..85268f9ba819b 100644 --- a/packages/playwright/ThirdPartyNotices.txt +++ b/packages/playwright/ThirdPartyNotices.txt @@ -64,23 +64,29 @@ This project incorporates components from the projects listed below. The origina - @jridgewell/sourcemap-codec@1.5.4 (https://github.com/jridgewell/sourcemaps) - @jridgewell/trace-mapping@0.3.29 (https://github.com/jridgewell/sourcemaps) - @sinclair/typebox@0.34.41 (https://github.com/sinclairzx81/typebox) +- @types/debug@4.1.12 (https://github.com/DefinitelyTyped/DefinitelyTyped) - @types/istanbul-lib-coverage@2.0.6 (https://github.com/DefinitelyTyped/DefinitelyTyped) - @types/istanbul-lib-report@3.0.3 (https://github.com/DefinitelyTyped/DefinitelyTyped) - @types/istanbul-reports@3.0.4 (https://github.com/DefinitelyTyped/DefinitelyTyped) +- @types/mdast@4.0.4 (https://github.com/DefinitelyTyped/DefinitelyTyped) +- @types/ms@2.1.0 (https://github.com/DefinitelyTyped/DefinitelyTyped) - @types/node@24.9.2 (https://github.com/DefinitelyTyped/DefinitelyTyped) - @types/stack-utils@2.0.3 (https://github.com/DefinitelyTyped/DefinitelyTyped) +- @types/unist@3.0.3 (https://github.com/DefinitelyTyped/DefinitelyTyped) - @types/yargs-parser@21.0.3 (https://github.com/DefinitelyTyped/DefinitelyTyped) - @types/yargs@17.0.34 (https://github.com/DefinitelyTyped/DefinitelyTyped) - ansi-colors@4.1.3 (https://github.com/doowb/ansi-colors) - ansi-styles@4.3.0 (https://github.com/chalk/ansi-styles) - ansi-styles@5.2.0 (https://github.com/chalk/ansi-styles) - anymatch@3.1.3 (https://github.com/micromatch/anymatch) +- bail@2.0.2 (https://github.com/wooorm/bail) - binary-extensions@2.2.0 (https://github.com/sindresorhus/binary-extensions) - braces@3.0.3 (https://github.com/micromatch/braces) - browserslist@4.25.1 (https://github.com/browserslist/browserslist) - buffer-from@1.1.2 (https://github.com/LinusU/buffer-from) - caniuse-lite@1.0.30001731 (https://github.com/browserslist/caniuse-lite) - chalk@4.1.2 (https://github.com/chalk/chalk) +- character-entities@2.0.2 (https://github.com/wooorm/character-entities) - chokidar@3.6.0 (https://github.com/paulmillr/chokidar) - ci-info@4.3.1 (https://github.com/watson/ci-info) - codemirror@5.65.18 (https://github.com/codemirror/CodeMirror) @@ -88,11 +94,16 @@ This project incorporates components from the projects listed below. The origina - color-name@1.1.4 (https://github.com/colorjs/color-name) - convert-source-map@2.0.0 (https://github.com/thlorenz/convert-source-map) - debug@4.4.0 (https://github.com/debug-js/debug) +- debug@4.4.3 (https://github.com/debug-js/debug) +- decode-named-character-reference@1.2.0 (https://github.com/wooorm/decode-named-character-reference) +- dequal@2.0.3 (https://github.com/lukeed/dequal) +- devlop@1.1.0 (https://github.com/wooorm/devlop) - electron-to-chromium@1.5.192 (https://github.com/kilian/electron-to-chromium) - enquirer@2.3.6 (https://github.com/enquirer/enquirer) - escalade@3.2.0 (https://github.com/lukeed/escalade) - escape-string-regexp@2.0.0 (https://github.com/sindresorhus/escape-string-regexp) - expect@30.2.0 (https://github.com/jestjs/jest) +- extend@3.0.2 (https://github.com/justmoon/node-extend) - fill-range@7.1.1 (https://github.com/jonschlinkert/fill-range) - gensync@1.0.0-beta.2 (https://github.com/loganfsmyth/gensync) - get-east-asian-width@1.3.0 (https://github.com/sindresorhus/get-east-asian-width) @@ -103,6 +114,7 @@ This project incorporates components from the projects listed below. The origina - is-extglob@2.1.1 (https://github.com/jonschlinkert/is-extglob) - is-glob@4.0.3 (https://github.com/micromatch/is-glob) - is-number@7.0.0 (https://github.com/jonschlinkert/is-number) +- is-plain-obj@4.1.0 (https://github.com/sindresorhus/is-plain-obj) - jest-diff@30.2.0 (https://github.com/jestjs/jest) - jest-matcher-utils@30.2.0 (https://github.com/jestjs/jest) - jest-message-util@30.2.0 (https://github.com/jestjs/jest) @@ -113,6 +125,29 @@ This project incorporates components from the projects listed below. The origina - jsesc@3.1.0 (https://github.com/mathiasbynens/jsesc) - json5@2.2.3 (https://github.com/json5/json5) - lru-cache@5.1.1 (https://github.com/isaacs/node-lru-cache) +- mdast-util-from-markdown@2.0.2 (https://github.com/syntax-tree/mdast-util-from-markdown) +- mdast-util-to-string@4.0.0 (https://github.com/syntax-tree/mdast-util-to-string) +- micromark-core-commonmark@2.0.3 (https://github.com/micromark/micromark/tree/main/packages/micromark-core-commonmark) +- micromark-factory-destination@2.0.1 (https://github.com/micromark/micromark/tree/main/packages/micromark-factory-destination) +- micromark-factory-label@2.0.1 (https://github.com/micromark/micromark/tree/main/packages/micromark-factory-label) +- micromark-factory-space@2.0.1 (https://github.com/micromark/micromark/tree/main/packages/micromark-factory-space) +- micromark-factory-title@2.0.1 (https://github.com/micromark/micromark/tree/main/packages/micromark-factory-title) +- micromark-factory-whitespace@2.0.1 (https://github.com/micromark/micromark/tree/main/packages/micromark-factory-whitespace) +- micromark-util-character@2.1.1 (https://github.com/micromark/micromark/tree/main/packages/micromark-util-character) +- micromark-util-chunked@2.0.1 (https://github.com/micromark/micromark/tree/main/packages/micromark-util-chunked) +- micromark-util-classify-character@2.0.1 (https://github.com/micromark/micromark/tree/main/packages/micromark-util-classify-character) +- micromark-util-combine-extensions@2.0.1 (https://github.com/micromark/micromark/tree/main/packages/micromark-util-combine-extensions) +- micromark-util-decode-numeric-character-reference@2.0.2 (https://github.com/micromark/micromark/tree/main/packages/micromark-util-decode-numeric-character-reference) +- micromark-util-decode-string@2.0.1 (https://github.com/micromark/micromark/tree/main/packages/micromark-util-decode-string) +- micromark-util-encode@2.0.1 (https://github.com/micromark/micromark/tree/main/packages/micromark-util-encode) +- micromark-util-html-tag-name@2.0.1 (https://github.com/micromark/micromark/tree/main/packages/micromark-util-html-tag-name) +- micromark-util-normalize-identifier@2.0.1 (https://github.com/micromark/micromark/tree/main/packages/micromark-util-normalize-identifier) +- micromark-util-resolve-all@2.0.1 (https://github.com/micromark/micromark/tree/main/packages/micromark-util-resolve-all) +- micromark-util-sanitize-uri@2.0.1 (https://github.com/micromark/micromark/tree/main/packages/micromark-util-sanitize-uri) +- micromark-util-subtokenize@2.1.0 (https://github.com/micromark/micromark/tree/main/packages/micromark-util-subtokenize) +- micromark-util-symbol@2.0.1 (https://github.com/micromark/micromark/tree/main/packages/micromark-util-symbol) +- micromark-util-types@2.0.2 (https://github.com/micromark/micromark/tree/main/packages/micromark-util-types) +- micromark@4.0.2 (https://github.com/micromark/micromark/tree/main/packages/micromark) - micromatch@4.0.8 (https://github.com/micromatch/micromatch) - ms@2.1.3 (https://github.com/vercel/ms) - node-releases@2.0.19 (https://github.com/chicoxyzzy/node-releases) @@ -123,6 +158,7 @@ This project incorporates components from the projects listed below. The origina - pretty-format@30.2.0 (https://github.com/jestjs/jest) - react-is@18.3.1 (https://github.com/facebook/react) - readdirp@3.6.0 (https://github.com/paulmillr/readdirp) +- remark-parse@11.0.0 (https://github.com/remarkjs/remark/tree/main/packages/remark-parse) - semver@6.3.1 (https://github.com/npm/node-semver) - slash@3.0.0 (https://github.com/sindresorhus/slash) - source-map-support@0.5.21 (https://github.com/evanw/node-source-map-support) @@ -131,8 +167,13 @@ This project incorporates components from the projects listed below. The origina - stoppable@1.1.0 (https://github.com/hunterloftis/stoppable) - supports-color@7.2.0 (https://github.com/chalk/supports-color) - to-regex-range@5.0.1 (https://github.com/micromatch/to-regex-range) +- trough@2.2.0 (https://github.com/wooorm/trough) - undici-types@7.16.0 (https://github.com/nodejs/undici) +- unified@11.0.5 (https://github.com/unifiedjs/unified) +- unist-util-stringify-position@4.0.0 (https://github.com/syntax-tree/unist-util-stringify-position) - update-browserslist-db@1.1.3 (https://github.com/browserslist/update-db) +- vfile-message@4.0.3 (https://github.com/vfile/vfile-message) +- vfile@6.0.3 (https://github.com/vfile/vfile) - yallist@3.1.1 (https://github.com/isaacs/yallist) %% @ampproject/remapping@2.2.1 NOTICES AND INFORMATION BEGIN HERE @@ -1923,6 +1964,32 @@ THE SOFTWARE. ========================================= END OF @sinclair/typebox@0.34.41 AND INFORMATION +%% @types/debug@4.1.12 NOTICES AND INFORMATION BEGIN HERE +========================================= +MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE +========================================= +END OF @types/debug@4.1.12 AND INFORMATION + %% @types/istanbul-lib-coverage@2.0.6 NOTICES AND INFORMATION BEGIN HERE ========================================= MIT License @@ -2001,6 +2068,58 @@ MIT License ========================================= END OF @types/istanbul-reports@3.0.4 AND INFORMATION +%% @types/mdast@4.0.4 NOTICES AND INFORMATION BEGIN HERE +========================================= +MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE +========================================= +END OF @types/mdast@4.0.4 AND INFORMATION + +%% @types/ms@2.1.0 NOTICES AND INFORMATION BEGIN HERE +========================================= +MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE +========================================= +END OF @types/ms@2.1.0 AND INFORMATION + %% @types/node@24.9.2 NOTICES AND INFORMATION BEGIN HERE ========================================= MIT License @@ -2053,6 +2172,32 @@ MIT License ========================================= END OF @types/stack-utils@2.0.3 AND INFORMATION +%% @types/unist@3.0.3 NOTICES AND INFORMATION BEGIN HERE +========================================= +MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE +========================================= +END OF @types/unist@3.0.3 AND INFORMATION + %% @types/yargs-parser@21.0.3 NOTICES AND INFORMATION BEGIN HERE ========================================= MIT License @@ -2179,6 +2324,33 @@ IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ========================================= END OF anymatch@3.1.3 AND INFORMATION +%% bail@2.0.2 NOTICES AND INFORMATION BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) 2015 Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF bail@2.0.2 AND INFORMATION + %% binary-extensions@2.2.0 NOTICES AND INFORMATION BEGIN HERE ========================================= MIT License @@ -2684,6 +2856,33 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI ========================================= END OF chalk@4.1.2 AND INFORMATION +%% character-entities@2.0.2 NOTICES AND INFORMATION BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) 2015 Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF character-entities@2.0.2 AND INFORMATION + %% chokidar@3.6.0 NOTICES AND INFORMATION BEGIN HERE ========================================= The MIT License (MIT) @@ -2852,6 +3051,110 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ========================================= END OF debug@4.4.0 AND INFORMATION +%% debug@4.4.3 NOTICES AND INFORMATION BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) 2014-2017 TJ Holowaychuk +Copyright (c) 2018-2021 Josh Junon + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software +and associated documentation files (the 'Software'), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT +LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF debug@4.4.3 AND INFORMATION + +%% decode-named-character-reference@1.2.0 NOTICES AND INFORMATION BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF decode-named-character-reference@1.2.0 AND INFORMATION + +%% dequal@2.0.3 NOTICES AND INFORMATION BEGIN HERE +========================================= +The MIT License (MIT) + +Copyright (c) Luke Edwards (lukeed.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +========================================= +END OF dequal@2.0.3 AND INFORMATION + +%% devlop@1.1.0 NOTICES AND INFORMATION BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) 2023 Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF devlop@1.1.0 AND INFORMATION + %% electron-to-chromium@1.5.192 NOTICES AND INFORMATION BEGIN HERE ========================================= Copyright 2018 Kilian Valkhof @@ -2943,6 +3246,33 @@ SOFTWARE. ========================================= END OF expect@30.2.0 AND INFORMATION +%% extend@3.0.2 NOTICES AND INFORMATION BEGIN HERE +========================================= +The MIT License (MIT) + +Copyright (c) 2014 Stefan Thomas + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF extend@3.0.2 AND INFORMATION + %% fill-range@7.1.1 NOTICES AND INFORMATION BEGIN HERE ========================================= The MIT License (MIT) @@ -3141,6 +3471,20 @@ THE SOFTWARE. ========================================= END OF is-number@7.0.0 AND INFORMATION +%% is-plain-obj@4.1.0 NOTICES AND INFORMATION BEGIN HERE +========================================= +MIT License + +Copyright (c) Sindre Sorhus (https://sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF is-plain-obj@4.1.0 AND INFORMATION + %% jest-diff@30.2.0 NOTICES AND INFORMATION BEGIN HERE ========================================= MIT License @@ -3402,14 +3746,635 @@ IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ========================================= END OF lru-cache@5.1.1 AND INFORMATION -%% micromatch@4.0.8 NOTICES AND INFORMATION BEGIN HERE +%% mdast-util-from-markdown@2.0.2 NOTICES AND INFORMATION BEGIN HERE ========================================= -The MIT License (MIT) +(The MIT License) -Copyright (c) 2014-present, Jon Schlinkert. +Copyright (c) Titus Wormer -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF mdast-util-from-markdown@2.0.2 AND INFORMATION + +%% mdast-util-to-string@4.0.0 NOTICES AND INFORMATION BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) 2015 Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF mdast-util-to-string@4.0.0 AND INFORMATION + +%% micromark-core-commonmark@2.0.3 NOTICES AND INFORMATION BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF micromark-core-commonmark@2.0.3 AND INFORMATION + +%% micromark-factory-destination@2.0.1 NOTICES AND INFORMATION BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF micromark-factory-destination@2.0.1 AND INFORMATION + +%% micromark-factory-label@2.0.1 NOTICES AND INFORMATION BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF micromark-factory-label@2.0.1 AND INFORMATION + +%% micromark-factory-space@2.0.1 NOTICES AND INFORMATION BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF micromark-factory-space@2.0.1 AND INFORMATION + +%% micromark-factory-title@2.0.1 NOTICES AND INFORMATION BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF micromark-factory-title@2.0.1 AND INFORMATION + +%% micromark-factory-whitespace@2.0.1 NOTICES AND INFORMATION BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF micromark-factory-whitespace@2.0.1 AND INFORMATION + +%% micromark-util-character@2.1.1 NOTICES AND INFORMATION BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF micromark-util-character@2.1.1 AND INFORMATION + +%% micromark-util-chunked@2.0.1 NOTICES AND INFORMATION BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF micromark-util-chunked@2.0.1 AND INFORMATION + +%% micromark-util-classify-character@2.0.1 NOTICES AND INFORMATION BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF micromark-util-classify-character@2.0.1 AND INFORMATION + +%% micromark-util-combine-extensions@2.0.1 NOTICES AND INFORMATION BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF micromark-util-combine-extensions@2.0.1 AND INFORMATION + +%% micromark-util-decode-numeric-character-reference@2.0.2 NOTICES AND INFORMATION BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF micromark-util-decode-numeric-character-reference@2.0.2 AND INFORMATION + +%% micromark-util-decode-string@2.0.1 NOTICES AND INFORMATION BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF micromark-util-decode-string@2.0.1 AND INFORMATION + +%% micromark-util-encode@2.0.1 NOTICES AND INFORMATION BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF micromark-util-encode@2.0.1 AND INFORMATION + +%% micromark-util-html-tag-name@2.0.1 NOTICES AND INFORMATION BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF micromark-util-html-tag-name@2.0.1 AND INFORMATION + +%% micromark-util-normalize-identifier@2.0.1 NOTICES AND INFORMATION BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF micromark-util-normalize-identifier@2.0.1 AND INFORMATION + +%% micromark-util-resolve-all@2.0.1 NOTICES AND INFORMATION BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF micromark-util-resolve-all@2.0.1 AND INFORMATION + +%% micromark-util-sanitize-uri@2.0.1 NOTICES AND INFORMATION BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF micromark-util-sanitize-uri@2.0.1 AND INFORMATION + +%% micromark-util-subtokenize@2.1.0 NOTICES AND INFORMATION BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF micromark-util-subtokenize@2.1.0 AND INFORMATION + +%% micromark-util-symbol@2.0.1 NOTICES AND INFORMATION BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF micromark-util-symbol@2.0.1 AND INFORMATION + +%% micromark-util-types@2.0.2 NOTICES AND INFORMATION BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF micromark-util-types@2.0.2 AND INFORMATION + +%% micromark@4.0.2 NOTICES AND INFORMATION BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF micromark@4.0.2 AND INFORMATION + +%% micromatch@4.0.8 NOTICES AND INFORMATION BEGIN HERE +========================================= +The MIT License (MIT) + +Copyright (c) 2014-present, Jon Schlinkert. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is @@ -3657,6 +4622,32 @@ SOFTWARE. ========================================= END OF readdirp@3.6.0 AND INFORMATION +%% remark-parse@11.0.0 NOTICES AND INFORMATION BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) 2014 Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +========================================= +END OF remark-parse@11.0.0 AND INFORMATION + %% semver@6.3.1 NOTICES AND INFORMATION BEGIN HERE ========================================= The ISC License @@ -3841,6 +4832,32 @@ THE SOFTWARE. ========================================= END OF to-regex-range@5.0.1 AND INFORMATION +%% trough@2.2.0 NOTICES AND INFORMATION BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) 2016 Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +========================================= +END OF trough@2.2.0 AND INFORMATION + %% undici-types@7.16.0 NOTICES AND INFORMATION BEGIN HERE ========================================= MIT License @@ -3867,6 +4884,59 @@ SOFTWARE. ========================================= END OF undici-types@7.16.0 AND INFORMATION +%% unified@11.0.5 NOTICES AND INFORMATION BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) 2015 Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +========================================= +END OF unified@11.0.5 AND INFORMATION + +%% unist-util-stringify-position@4.0.0 NOTICES AND INFORMATION BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) 2016 Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF unist-util-stringify-position@4.0.0 AND INFORMATION + %% update-browserslist-db@1.1.3 NOTICES AND INFORMATION BEGIN HERE ========================================= The MIT License (MIT) @@ -3892,6 +4962,59 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ========================================= END OF update-browserslist-db@1.1.3 AND INFORMATION +%% vfile-message@4.0.3 NOTICES AND INFORMATION BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF vfile-message@4.0.3 AND INFORMATION + +%% vfile@6.0.3 NOTICES AND INFORMATION BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) 2015 Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +========================================= +END OF vfile@6.0.3 AND INFORMATION + %% yallist@3.1.1 NOTICES AND INFORMATION BEGIN HERE ========================================= The ISC License @@ -3914,6 +5037,6 @@ END OF yallist@3.1.1 AND INFORMATION SUMMARY BEGIN HERE ========================================= -Total Packages: 130 +Total Packages: 171 ========================================= END OF SUMMARY \ No newline at end of file diff --git a/packages/playwright/bundles/babel/package-lock.json b/packages/playwright/bundles/babel/package-lock.json index eeb420a495b60..461cfebb4dd0e 100644 --- a/packages/playwright/bundles/babel/package-lock.json +++ b/packages/playwright/bundles/babel/package-lock.json @@ -30,7 +30,8 @@ "@babel/plugin-transform-private-methods": "^7.27.1", "@babel/plugin-transform-private-property-in-object": "^7.27.1", "@babel/plugin-transform-react-jsx": "^7.27.1", - "@babel/preset-typescript": "^7.27.1" + "@babel/preset-typescript": "^7.27.1", + "@jridgewell/gen-mapping": "^0.3.12" }, "devDependencies": { "@types/babel__code-frame": "^7.0.6", diff --git a/packages/playwright/bundles/babel/package.json b/packages/playwright/bundles/babel/package.json index 379469c6e242d..1f906eac06d79 100644 --- a/packages/playwright/bundles/babel/package.json +++ b/packages/playwright/bundles/babel/package.json @@ -25,7 +25,8 @@ "@babel/plugin-transform-private-methods": "^7.27.1", "@babel/plugin-transform-private-property-in-object": "^7.27.1", "@babel/plugin-transform-react-jsx": "^7.27.1", - "@babel/preset-typescript": "^7.27.1" + "@babel/preset-typescript": "^7.27.1", + "@jridgewell/gen-mapping": "^0.3.12" }, "devDependencies": { "@types/babel__code-frame": "^7.0.6", diff --git a/packages/playwright/bundles/babel/src/babelBundleImpl.ts b/packages/playwright/bundles/babel/src/babelBundleImpl.ts index 27d94349b6a8a..9032cbb1e7e4d 100644 --- a/packages/playwright/bundles/babel/src/babelBundleImpl.ts +++ b/packages/playwright/bundles/babel/src/babelBundleImpl.ts @@ -22,10 +22,12 @@ import traverseFunction from '@babel/traverse'; import type { BabelFileResult, NodePath, PluginObj, TransformOptions } from '@babel/core'; import type { TemplateBuilder } from '@babel/template'; import type { ImportDeclaration, TSExportAssignment } from '@babel/types'; +import type { EncodedSourceMap } from '@jridgewell/gen-mapping'; export { codeFrameColumns } from '@babel/code-frame'; export { declare } from '@babel/helper-plugin-utils'; export { types } from '@babel/core'; +export * as genMapping from '@jridgewell/gen-mapping'; export const traverse = traverseFunction; function babelTransformOptions(isTypeScript: boolean, isModule: boolean, pluginsPrologue: [string, any?][], pluginsEpilogue: [string, any?][]): TransformOptions { @@ -120,7 +122,7 @@ function isTypeScript(filename: string) { return filename.endsWith('.ts') || filename.endsWith('.tsx') || filename.endsWith('.mts') || filename.endsWith('.cts'); } -export function babelTransform(code: string, filename: string, isModule: boolean, pluginsPrologue: [string, any?][], pluginsEpilogue: [string, any?][]): BabelFileResult | null { +export function babelTransform(code: string, filename: string, isModule: boolean, pluginsPrologue: [string, any?][], pluginsEpilogue: [string, any?][], inputSourceMap?: EncodedSourceMap): BabelFileResult | null { if (isTransforming) return null; @@ -128,6 +130,17 @@ export function babelTransform(code: string, filename: string, isModule: boolean isTransforming = true; try { const options = babelTransformOptions(isTypeScript(filename), isModule, pluginsPrologue, pluginsEpilogue); + if (inputSourceMap) { + options.inputSourceMap = { + ...inputSourceMap, + sources: inputSourceMap.sources.map(s => s || ''), + names: [...inputSourceMap.names], + sourceRoot: inputSourceMap.sourceRoot, + sourcesContent: inputSourceMap.sourcesContent?.map(s => s || ''), + mappings: inputSourceMap.mappings, + file: inputSourceMap.file || '', + }; + } return babel.transform(code, { filename, ...options }); } finally { isTransforming = false; diff --git a/packages/playwright/bundles/utils/package-lock.json b/packages/playwright/bundles/utils/package-lock.json index 95f4c43dc1d90..0fef2e6653632 100644 --- a/packages/playwright/bundles/utils/package-lock.json +++ b/packages/playwright/bundles/utils/package-lock.json @@ -12,14 +12,40 @@ "enquirer": "2.3.6", "get-east-asian-width": "1.3.0", "json5": "2.2.3", + "remark-parse": "^11.0.0", "source-map-support": "0.5.21", - "stoppable": "1.1.0" + "stoppable": "1.1.0", + "unified": "^11.0.5" }, "devDependencies": { "@types/source-map-support": "^0.5.4", "@types/stoppable": "^1.1.1" } }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "license": "MIT" + }, "node_modules/@types/node": { "version": "18.6.4", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.6.4.tgz", @@ -44,6 +70,12 @@ "@types/node": "*" } }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, "node_modules/ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", @@ -64,6 +96,16 @@ "node": ">= 8" } }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -88,6 +130,16 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -111,6 +163,58 @@ "fsevents": "~2.3.2" } }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz", + "integrity": "sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==", + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/enquirer": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", @@ -122,6 +226,12 @@ "node": ">=8.6" } }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -207,6 +317,18 @@ "node": ">=0.12.0" } }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -218,6 +340,491 @@ "node": ">=6" } }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", + "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -248,6 +855,22 @@ "node": ">=8.10.0" } }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -284,9 +907,100 @@ "engines": { "node": ">=8.0" } + }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } } }, "dependencies": { + "@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "requires": { + "@types/ms": "*" + } + }, + "@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "requires": { + "@types/unist": "*" + } + }, + "@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==" + }, "@types/node": { "version": "18.6.4", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.6.4.tgz", @@ -311,6 +1025,11 @@ "@types/node": "*" } }, + "@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" + }, "ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", @@ -325,6 +1044,11 @@ "picomatch": "^2.0.4" } }, + "bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==" + }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -343,6 +1067,11 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, + "character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==" + }, "chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -358,6 +1087,35 @@ "readdirp": "~3.6.0" } }, + "debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "requires": { + "ms": "^2.1.3" + } + }, + "decode-named-character-reference": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz", + "integrity": "sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==", + "requires": { + "character-entities": "^2.0.0" + } + }, + "dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==" + }, + "devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "requires": { + "dequal": "^2.0.0" + } + }, "enquirer": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", @@ -366,6 +1124,11 @@ "ansi-colors": "^4.1.1" } }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, "fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -419,11 +1182,259 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, + "is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==" + }, "json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" }, + "mdast-util-from-markdown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", + "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", + "requires": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + } + }, + "mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "requires": { + "@types/mdast": "^4.0.0" + } + }, + "micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "requires": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-core-commonmark": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "requires": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "requires": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "requires": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "requires": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "requires": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "requires": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "requires": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "requires": { + "micromark-util-symbol": "^2.0.0" + } + }, + "micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "requires": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "requires": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "requires": { + "micromark-util-symbol": "^2.0.0" + } + }, + "micromark-util-decode-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "requires": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==" + }, + "micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==" + }, + "micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "requires": { + "micromark-util-symbol": "^2.0.0" + } + }, + "micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "requires": { + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "requires": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "requires": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==" + }, + "micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==" + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -442,6 +1453,17 @@ "picomatch": "^2.2.1" } }, + "remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "requires": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + } + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -468,6 +1490,51 @@ "requires": { "is-number": "^7.0.0" } + }, + "trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==" + }, + "unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "requires": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + } + }, + "unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "requires": { + "@types/unist": "^3.0.0" + } + }, + "vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "requires": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + } + }, + "vfile-message": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", + "requires": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + } } } } diff --git a/packages/playwright/bundles/utils/package.json b/packages/playwright/bundles/utils/package.json index c6f39dd86fa10..dc0bed7efc58c 100644 --- a/packages/playwright/bundles/utils/package.json +++ b/packages/playwright/bundles/utils/package.json @@ -7,8 +7,10 @@ "enquirer": "2.3.6", "get-east-asian-width": "1.3.0", "json5": "2.2.3", + "remark-parse": "11.0.0", "source-map-support": "0.5.21", - "stoppable": "1.1.0" + "stoppable": "1.1.0", + "unified": "11.0.5" }, "devDependencies": { "@types/source-map-support": "^0.5.4", diff --git a/packages/playwright/bundles/utils/src/utilsBundleImpl.ts b/packages/playwright/bundles/utils/src/utilsBundleImpl.ts index 6e75f7cf6e3a6..1af058f18701d 100644 --- a/packages/playwright/bundles/utils/src/utilsBundleImpl.ts +++ b/packages/playwright/bundles/utils/src/utilsBundleImpl.ts @@ -31,3 +31,9 @@ export const chokidar = chokidarLibrary; import * as getEastAsianWidthLibrary from 'get-east-asian-width'; export const getEastAsianWidth = getEastAsianWidthLibrary; + +import * as unifiedLibrary from 'unified'; +export const unified = unifiedLibrary; + +import remarkParseLibrary from 'remark-parse'; +export const remarkParse = remarkParseLibrary; diff --git a/packages/playwright/src/common/config.ts b/packages/playwright/src/common/config.ts index 4b6c466cd41e7..bafd9ecc8de61 100644 --- a/packages/playwright/src/common/config.ts +++ b/packages/playwright/src/common/config.ts @@ -118,7 +118,7 @@ export class FullConfigInternal { updateSnapshots: takeFirst(configCLIOverrides.updateSnapshots, userConfig.updateSnapshots, 'missing'), updateSourceMethod: takeFirst(configCLIOverrides.updateSourceMethod, userConfig.updateSourceMethod, 'patch'), version: require('../../package.json').version, - workers: resolveWorkers(takeFirst(configCLIOverrides.debug ? 1 : undefined, configCLIOverrides.workers, userConfig.workers, '50%')), + workers: resolveWorkers(takeFirst(configCLIOverrides.pause ? 1 : undefined, configCLIOverrides.workers, userConfig.workers, '50%')), webServer: null, }; for (const key in userConfig) { @@ -196,7 +196,7 @@ export class FullProjectInternal { testDir, snapshotDir: takeFirst(pathResolve(configDir, projectConfig.snapshotDir), pathResolve(configDir, config.snapshotDir), testDir), testIgnore: takeFirst(projectConfig.testIgnore, config.testIgnore, []), - testMatch: takeFirst(projectConfig.testMatch, config.testMatch, '**/*.@(spec|test).?(c|m)[jt]s?(x)'), + testMatch: takeFirst(projectConfig.testMatch, config.testMatch, '**/*.@(spec|test).{md,?(c|m)[jt]s?(x)}'), timeout: takeFirst(configCLIOverrides.debug ? 0 : undefined, configCLIOverrides.timeout, projectConfig.timeout, config.timeout, defaultTimeout), use: mergeObjects(config.use, projectConfig.use, configCLIOverrides.use), dependencies: projectConfig.dependencies || [], diff --git a/packages/playwright/src/common/ipc.ts b/packages/playwright/src/common/ipc.ts index 8c20d80e97cfa..c6aa1b0a71f26 100644 --- a/packages/playwright/src/common/ipc.ts +++ b/packages/playwright/src/common/ipc.ts @@ -31,6 +31,7 @@ export type ConfigCLIOverrides = { maxFailures?: number; outputDir?: string; preserveOutputDir?: boolean; + pause?: boolean; quiet?: boolean; repeatEach?: number; retries?: number; @@ -91,6 +92,7 @@ export type TestInfoErrorImpl = TestInfoError; export type TestPausedPayload = { testId: string; errors: TestInfoErrorImpl[]; + status: TestStatus; }; export type ResumePayload = {}; diff --git a/packages/playwright/src/program.ts b/packages/playwright/src/program.ts index c48a605a8f57f..0df97a777ca29 100644 --- a/packages/playwright/src/program.ts +++ b/packages/playwright/src/program.ts @@ -308,6 +308,7 @@ function overridesFromOptions(options: { [key: string]: any }): ConfigCLIOverrid updateSourceMethod: options.updateSourceMethod, runAgents: options.runAgents, workers: options.workers, + pause: options.pause ? true : undefined, }; if (options.browser) { @@ -323,10 +324,11 @@ function overridesFromOptions(options: { [key: string]: any }): ConfigCLIOverrid }); } - if (options.headed || options.debug) + if (options.headed || options.debug || overrides.pause) overrides.use = { headless: false }; if (!options.ui && options.debug) { overrides.debug = true; + overrides.pause = true; process.env.PWDEBUG = '1'; } if (!options.ui && options.trace) { @@ -401,7 +403,7 @@ const kTraceModes: TraceMode[] = ['on', 'off', 'on-first-retry', 'on-all-retries const testOptions: [string, { description: string, choices?: string[], preset?: string }][] = [ /* deprecated */ ['--browser ', { description: `Browser to use for tests, one of "all", "chromium", "firefox" or "webkit" (default: "chromium")` }], ['-c, --config ', { description: `Configuration file, or a test directory with optional "playwright.config.{m,c}?{js,ts}"` }], - ['--debug', { description: `Run tests with Playwright Inspector. Shortcut for "PWDEBUG=1" environment variable and "--timeout=0 --max-failures=1 --headed --workers=1" options` }], + ['--debug', { description: `Run tests with Playwright Inspector. Shortcut for "PWDEBUG=1" environment variable and "--timeout=0 --max-failures=1 --headed --workers=1 --pause" options` }], ['--fail-on-flaky-tests', { description: `Fail if any test is flagged as flaky (default: false)` }], ['--forbid-only', { description: `Fail if test.only is called (default: false)` }], ['--fully-parallel', { description: `Run all tests in parallel (default: false)` }], @@ -417,6 +419,7 @@ const testOptions: [string, { description: string, choices?: string[], preset?: ['--output ', { description: `Folder for output artifacts (default: "test-results")` }], ['--only-changed [ref]', { description: `Only run test files that have been changed between 'HEAD' and 'ref'. Defaults to running all uncommitted changes. Only supports Git.` }], ['--pass-with-no-tests', { description: `Makes test run succeed even if no tests were found` }], + ['--pause', { description: `Run tests in headed mode and pause at the end of test execution` }], ['--project ', { description: `Only run tests from the specified list of projects, supports '*' wildcard (default: run all projects)` }], ['--quiet', { description: `Suppress stdio` }], ['--repeat-each ', { description: `Run each test N times (default: 1)` }], diff --git a/packages/playwright/src/reporters/base.ts b/packages/playwright/src/reporters/base.ts index e3fde36e373cf..f94ffebf29bf2 100644 --- a/packages/playwright/src/reporters/base.ts +++ b/packages/playwright/src/reporters/base.ts @@ -359,20 +359,42 @@ export class TerminalReporter implements ReporterV2 { return formatError(this.screen, error); } + formatSingleResult(test: TestCase, result: TestResult, index?: number): string { + return formatSingleResult(this.screen, this.config, test, result, index); + } + writeLine(line?: string) { this.screen.stdout?.write(line ? line + '\n' : '\n'); } } +function formatSingleResult(screen: Screen, config: FullConfig, test: TestCase, result: TestResult, index?: number): string { + const lines: string[] = []; + const header = formatTestHeader(screen, config, test, { indent: ' ', index }); + lines.push(test.outcome() === 'unexpected' ? screen.colors.red(header) : screen.colors.yellow(header)); + if (test.outcome() === 'unexpected') { + const errorDetails = formatResultFailure(screen, test, result, ' '); + if (errorDetails.length > 0) + lines.push(''); + for (const error of errorDetails) + lines.push(error.message, ''); + } + return lines.join('\n'); +} + export function formatFailure(screen: Screen, config: FullConfig, test: TestCase, index?: number, options?: TerminalReporterOptions): string { const lines: string[] = []; - const header = formatTestHeader(screen, config, test, { indent: ' ', index, mode: 'error', includeTestId: options?.includeTestId }); - lines.push(screen.colors.red(header)); + let printedHeader = false; for (const result of test.results) { const resultLines: string[] = []; const errors = formatResultFailure(screen, test, result, ' '); if (!errors.length) continue; + if (!printedHeader) { + const header = formatTestHeader(screen, config, test, { indent: ' ', index, mode: 'error', includeTestId: options?.includeTestId }); + lines.push(screen.colors.red(header)); + printedHeader = true; + } if (result.retry) { resultLines.push(''); resultLines.push(screen.colors.gray(separator(screen, ` Retry #${result.retry}`))); @@ -455,6 +477,12 @@ function quotePathIfNeeded(path: string): string { return path; } +const kReportedSymbol = Symbol('reported'); + +export function markErrorsAsReported(result: TestResult) { + (result as any)[kReportedSymbol] = result.errors.length; +} + export function formatResultFailure(screen: Screen, test: TestCase, result: TestResult, initialIndent: string): ErrorDetails[] { const errorDetails: ErrorDetails[] = []; @@ -469,7 +497,8 @@ export function formatResultFailure(screen: Screen, test: TestCase, result: Test }); } - for (const error of result.errors) { + const reportedIndex = (result as any)[kReportedSymbol] || 0; + for (const error of result.errors.slice(reportedIndex)) { const formattedError = formatError(screen, error); errorDetails.push({ message: indent(formattedError.message, initialIndent), diff --git a/packages/playwright/src/reporters/line.ts b/packages/playwright/src/reporters/line.ts index 3c34f22308d3e..4bcda258f6154 100644 --- a/packages/playwright/src/reporters/line.ts +++ b/packages/playwright/src/reporters/line.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { TerminalReporter } from './base'; +import { markErrorsAsReported, TerminalReporter } from './base'; import type { FullResult, Suite, TestCase, TestError, TestResult, TestStep } from '../../types/testReporter'; @@ -78,6 +78,23 @@ class LineReporter extends TerminalReporter { this._updateLine(test, result, step.parent); } + async onTestPaused(test: TestCase, result: TestResult) { + // without TTY, user cannot interrupt the pause. let's skip it. + if (!process.stdin.isTTY && !process.env.PW_TEST_DEBUG_REPORTERS) + return; + + if (!process.env.PW_TEST_DEBUG_REPORTERS) + this.screen.stdout.write(`\u001B[1A\u001B[2K`); + + this.writeLine(this.formatSingleResult(test, result, test.outcome() === 'unexpected' ? ++this._failures : undefined)); + markErrorsAsReported(result); + this.writeLine(this.screen.colors.yellow(` Paused ${test.outcome() === 'unexpected' ? 'on error' : 'at test end'}. Press Ctrl+C to end.`) + '\n\n'); + + this._updateLine(test, result, undefined); + + await new Promise(() => {}); + } + override onTestEnd(test: TestCase, result: TestResult) { super.onTestEnd(test, result); if (!this.willRetry(test) && (test.outcome() === 'flaky' || test.outcome() === 'unexpected' || result.status === 'interrupted')) { diff --git a/packages/playwright/src/runner/dispatcher.ts b/packages/playwright/src/runner/dispatcher.ts index dd8defedda16a..db5873fec3913 100644 --- a/packages/playwright/src/runner/dispatcher.ts +++ b/packages/playwright/src/runner/dispatcher.ts @@ -615,6 +615,7 @@ class JobDispatcher { } }; + result.status = params.status; result.errors = params.errors; result.error = result.errors[0]; diff --git a/packages/playwright/src/runner/projectUtils.ts b/packages/playwright/src/runner/projectUtils.ts index 3ad639a9955ce..bbe4fb4c9e093 100644 --- a/packages/playwright/src/runner/projectUtils.ts +++ b/packages/playwright/src/runner/projectUtils.ts @@ -145,7 +145,7 @@ export function buildDependentProjects(forProjects: FullProjectInternal[], proje } export async function collectFilesForProject(project: FullProjectInternal, fsCache = new Map()): Promise { - const extensions = new Set(['.js', '.ts', '.mjs', '.mts', '.cjs', '.cts', '.jsx', '.tsx', '.mjsx', '.mtsx', '.cjsx', '.ctsx']); + const extensions = new Set(['.js', '.ts', '.mjs', '.mts', '.cjs', '.cts', '.jsx', '.tsx', '.mjsx', '.mtsx', '.cjsx', '.ctsx', '.md']); const testFileExtension = (file: string) => extensions.has(path.extname(file)); const allFiles = await cachedCollectFiles(project.project.testDir, project.respectGitIgnore, fsCache); const testMatch = createFileMatcher(project.project.testMatch); diff --git a/packages/playwright/src/runner/testRunner.ts b/packages/playwright/src/runner/testRunner.ts index c75f75a815172..564347ac780fe 100644 --- a/packages/playwright/src/runner/testRunner.ts +++ b/packages/playwright/src/runner/testRunner.ts @@ -482,7 +482,7 @@ export async function runAllTestsWithConfig(config: FullConfigInternal): Promise ...createRunTestsTasks(config), ]; - const testRun = new TestRun(config, reporter, { pauseAtEnd: config.configCLIOverrides.debug, pauseOnError: config.configCLIOverrides.debug }); + const testRun = new TestRun(config, reporter, { pauseAtEnd: config.configCLIOverrides.pause, pauseOnError: config.configCLIOverrides.pause }); const status = await runTasks(testRun, tasks, config.config.globalTimeout); // Calling process.exit() might truncate large stdout/stderr output. diff --git a/packages/playwright/src/transform/babelBundle.ts b/packages/playwright/src/transform/babelBundle.ts index ce61eecc90a66..9f37cdfcf1898 100644 --- a/packages/playwright/src/transform/babelBundle.ts +++ b/packages/playwright/src/transform/babelBundle.ts @@ -15,14 +15,17 @@ */ import type { BabelFileResult, ParseResult } from '../../bundles/babel/node_modules/@types/babel__core'; +import type { EncodedSourceMap } from '../../bundles/babel/node_modules/@jridgewell/gen-mapping'; export const codeFrameColumns: typeof import('../../bundles/babel/node_modules/@types/babel__code-frame').codeFrameColumns = require('./babelBundleImpl').codeFrameColumns; export const declare: typeof import('../../bundles/babel/node_modules/@types/babel__helper-plugin-utils').declare = require('./babelBundleImpl').declare; export const types: typeof import('../../bundles/babel/node_modules/@types/babel__core').types = require('./babelBundleImpl').types; export const traverse: typeof import('../../bundles/babel/node_modules/@types/babel__traverse').default = require('./babelBundleImpl').traverse; export type BabelPlugin = [string, any?]; -export type BabelTransformFunction = (code: string, filename: string, isModule: boolean, pluginsPrefix: BabelPlugin[], pluginsSuffix: BabelPlugin[]) => BabelFileResult | null; +export type BabelTransformFunction = (code: string, filename: string, isModule: boolean, pluginsPrefix: BabelPlugin[], pluginsSuffix: BabelPlugin[], inputSourceMap?: EncodedSourceMap) => BabelFileResult | null; export const babelTransform: BabelTransformFunction = require('./babelBundleImpl').babelTransform; export type BabelParseFunction = (code: string, filename: string, isModule: boolean) => ParseResult; export const babelParse: BabelParseFunction = require('./babelBundleImpl').babelParse; export type { NodePath, PluginObj, types as T } from '../../bundles/babel/node_modules/@types/babel__core'; export type { BabelAPI } from '../../bundles/babel/node_modules/@types/babel__helper-plugin-utils'; +export type { EncodedSourceMap } from '../../bundles/babel/node_modules/@jridgewell/gen-mapping'; +export const genMapping: typeof import('../../bundles/babel/node_modules/@jridgewell/gen-mapping') = require('./babelBundleImpl').genMapping; diff --git a/packages/playwright/src/transform/compilationCache.ts b/packages/playwright/src/transform/compilationCache.ts index d132f5f50dbfc..d1420ac699dc3 100644 --- a/packages/playwright/src/transform/compilationCache.ts +++ b/packages/playwright/src/transform/compilationCache.ts @@ -73,6 +73,8 @@ export function installSourceMapSupport() { environment: 'node', handleUncaughtExceptions: false, retrieveSourceMap(source) { + if (source.startsWith('file://') && !sourceMaps.has(source)) + source = source.substring('file://'.length); if (!sourceMaps.has(source)) return null; const sourceMapPath = sourceMaps.get(source)!; diff --git a/packages/playwright/src/transform/md.ts b/packages/playwright/src/transform/md.ts new file mode 100644 index 0000000000000..351b507d149a8 --- /dev/null +++ b/packages/playwright/src/transform/md.ts @@ -0,0 +1,229 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import fs from 'fs'; +import path from 'path'; + +import { parseMarkdown } from '../utilsBundle'; +import { genMapping } from './babelBundle'; + +import type * as mdast from 'mdast'; +import type { EncodedSourceMap } from './babelBundle'; + +type Props = [string, Line][]; +// source is 1-based +type Line = { text: string; source?: { filename: string; line: number; column: number } }; +type Test = { title: Line, lines: Line[], props: Props }; + +export function transformMDToTS(code: string, filename: string): { code: string, map: EncodedSourceMap } { + const parsed = parseSpec(code, filename); + let fixtures = resolveFixtures(filename, parsed.props.find(prop => prop[0] === 'fixtures')?.[1]); + const seed = parsed.props.find(prop => prop[0] === 'seed')?.[1]; + if (seed) { + const seedFile = path.resolve(path.dirname(filename), seed.text); + const seedContents = fs.readFileSync(seedFile, 'utf-8'); + const parsedSeed = parseSpec(seedContents, seedFile); + if (parsedSeed.tests.length !== 1) + throw new Error(`while parsing ${seedFile}: seed file must contain exactly one test`); + if (parsedSeed.tests[0].props.length) + throw new Error(`while parsing ${seedFile}: seed test must not have properties`); + for (const test of parsed.tests) + test.lines = parsedSeed.tests[0].lines.concat(test.lines); + const seedFixtures = resolveFixtures(seedFile, parsedSeed.props.find(prop => prop[0] === 'fixtures')?.[1]); + if (seedFixtures && fixtures) + throw new Error(`while parsing ${filename}: either seed or test can specify fixtures, but not both`); + fixtures ??= seedFixtures; + } + + const map = new genMapping.GenMapping({}); + const lines: string[] = []; + const addLine = (line: Line) => { + lines.push(line.text); + if (line.source) { + genMapping.addMapping(map, { + generated: { line: lines.length, column: 0 }, + source: line.source.filename, + original: { line: line.source.line, column: line.source.column - 1 }, + }); + } + }; + + if (fixtures) + addLine({ text: `import { test, expect } from ${escapeString(path.relative(path.dirname(filename), fixtures.text))};`, source: fixtures.source }); + else + addLine({ text: `import { test, expect } from '@playwright/test';` }); + addLine({ text: `test.describe(${escapeString(parsed.describe.text)}, () => {`, source: parsed.describe.source }); + for (const test of parsed.tests) { + const tags: string[] = []; + const annotations: { type: string, description: string }[] = []; + for (const [key, value] of test.props) { + if (key === 'tag') { + tags.push(...value.text.split(' ').map(s => s.trim()).filter(s => !!s)); + } else if (key === 'annotation') { + if (!value.text.includes('=')) + throw new Error(`while parsing ${filename}: annotation must be in format "type=description", found "${value}"`); + const [type, description] = value.text.split('=').map(s => s.trim()); + annotations.push({ type, description }); + } + } + let props = ''; + if (tags.length || annotations.length) { + props = '{ '; + if (tags.length) + props += `tag: [${tags.map(tag => escapeString(tag)).join(', ')}], `; + if (annotations.length) + props += `annotation: [${annotations.map(a => `{ type: ${escapeString(a.type)}, description: ${escapeString(a.description)} }`).join(', ')}], `; + props += '}, '; + } + // TODO: proper source mapping for props + addLine({ text: ` test(${escapeString(test.title.text)}, ${props}async ({ page, agent }) => {`, source: test.title.source }); + for (const line of test.lines) + addLine({ text: ' ' + line.text, source: line.source }); + addLine({ text: ` });`, source: test.title.source }); + } + addLine({ text: `});`, source: parsed.describe.source }); + addLine({ text: `` }); + + const encodedMap = genMapping.toEncodedMap(map); + const result = lines.join('\n'); + return { code: result, map: encodedMap }; +} + +function resolveFixtures(filename: string, prop: Line | undefined): Line | undefined { + if (!prop) + return; + return { text: path.resolve(path.dirname(filename), prop.text), source: prop.source }; +} + +function escapeString(s: string): string { + return `'` + s.replace(/\n/g, ' ').replace(/'/g, `\\'`) + `'`; +} + +function parsingError(filename: string, node: mdast.Node | undefined, message: string): Error { + const position = node?.position?.start ? ` at ${node.position.start.line}:${node.position.start.column}` : ''; + return new Error(`while parsing ${filename}${position}: ${message}`); +} + +function asText(filename: string, node: mdast.Parent, errorMessage: string, skipChild?: mdast.Node): Line { + let children = node.children.filter(child => child !== skipChild); + while (children.length === 1 && children[0].type === 'paragraph') + children = children[0].children; + if (children.length !== 1 || children[0].type !== 'text') + throw parsingError(filename, node, errorMessage); + return { text: children[0].value, source: node.position ? { filename, line: node.position.start.line, column: node.position.start.column } : undefined }; +} + +function parseSpec(content: string, filename: string): { describe: Line, tests: Test[], props: Props } { + const root = parseMarkdown(content); + const props: Props = []; + + const children = [...root.children]; + const describeNode = children[0]; + children.shift(); + if (describeNode?.type !== 'heading' || describeNode.depth !== 2) + throw parsingError(filename, describeNode, `describe title must be ##`); + const describe = asText(filename, describeNode, `describe title must be ##`); + + if (children[0]?.type === 'list') { + parseProps(filename, children[0], props); + children.shift(); + } + + const tests: Test[] = []; + while (children.length) { + let nextIndex = children.findIndex((n, i) => i > 0 && n.type === 'heading' && n.depth === 3); + if (nextIndex === -1) + nextIndex = children.length; + const testNodes = children.splice(0, nextIndex); + tests.push(parseTest(filename, testNodes)); + } + + return { describe, tests, props }; +} + +function parseProp(filename: string, node: mdast.ListItem, props: Props) { + const propText = asText(filename, node, `property must be a list item without children`); + const match = propText.text.match(/^([^:]+):(.*)$/); + if (!match) + throw parsingError(filename, node, `property must be in format "key: value"`); + props.push([match[1].trim(), { text: match[2].trim(), source: propText.source }]); +} + +function parseProps(filename: string, node: mdast.List, props: Props) { + for (const prop of node.children || []) { + if (prop.type !== 'listItem') + throw parsingError(filename, prop, `property must be a list item without children`); + parseProp(filename, prop, props); + } +} + +function parseTest(filename: string, nodes: mdast.Node[]): Test { + const titleNode = nodes[0] as mdast.Heading; + nodes.shift(); + if (titleNode.type !== 'heading' || titleNode.depth !== 3) + throw parsingError(filename, titleNode, `test title must be ###`); + const title = asText(filename, titleNode, `test title must be ###`); + + const props: Props = []; + let handlingProps = true; + + const lines: Line[] = []; + const visit = (node: mdast.Node, indent: string) => { + if (node.type === 'list') { + for (const child of (node as mdast.List).children) + visit(child, indent); + return; + } + if (node.type === 'listItem') { + const listItem = node as mdast.ListItem; + const lastChild = listItem.children[listItem.children.length - 1]; + if (lastChild?.type === 'code') { + handlingProps = false; + const { text, source } = asText(filename, listItem, `code step must be a list item with a single code block`, lastChild); + lines.push({ text: `${indent}await test.step(${escapeString(text)}, async () => {`, source }); + for (const [index, code] of lastChild.value.split('\n').entries()) + lines.push({ text: indent + ' ' + code, source: lastChild.position ? { filename: filename, line: lastChild.position.start.line + 1 + index, column: lastChild.position.start.column } : undefined }); + lines.push({ text: `${indent}});`, source }); + } else { + const { text, source } = asText(filename, listItem, `step must contain a single instruction`, lastChild?.type === 'list' ? lastChild : undefined); + let isGroup = false; + if (handlingProps && lastChild?.type !== 'list' && ['tag:', 'annotation:'].some(prefix => text.startsWith(prefix))) { + parseProp(filename, listItem, props); + } else if (text.startsWith('group:')) { + isGroup = true; + lines.push({ text: `${indent}await test.step(${escapeString(text.substring('group:'.length).trim())}, async () => {`, source }); + } else if (text.startsWith('expect:')) { + handlingProps = false; + const assertion = text.substring('expect:'.length).trim(); + lines.push({ text: `${indent}await agent.expect(${escapeString(assertion)});`, source }); + } else if (!text.startsWith('//')) { + handlingProps = false; + lines.push({ text: `${indent}await agent.perform(${escapeString(text)});`, source }); + } + if (lastChild?.type === 'list') + visit(lastChild, indent + (isGroup ? ' ' : '')); + if (isGroup) + lines.push({ text: `${indent}});`, source }); + } + } else { + throw parsingError(filename, node, `test step must be a markdown list item`); + } + }; + + for (const node of nodes) + visit(node, ''); + return { title, lines, props }; +} diff --git a/packages/playwright/src/transform/transform.ts b/packages/playwright/src/transform/transform.ts index 0aa637572b3bf..862023cc5f9b8 100644 --- a/packages/playwright/src/transform/transform.ts +++ b/packages/playwright/src/transform/transform.ts @@ -26,8 +26,9 @@ import { createFileMatcher, fileIsModule, resolveImportSpecifierAfterMapping } f import { sourceMapSupport } from '../utilsBundle'; import { belongsToNodeModules, currentFileDepsCollector, getFromCompilationCache, installSourceMapSupport } from './compilationCache'; import { addHook } from '../third_party/pirates'; +import { transformMDToTS } from './md'; -import type { BabelPlugin, BabelTransformFunction } from './babelBundle'; +import type { BabelPlugin, BabelTransformFunction, EncodedSourceMap } from './babelBundle'; import type { Location } from '../../types/testReporter'; import type { LoadedTsConfig } from '../third_party/tsconfig-loader'; import type { Matcher } from '../util'; @@ -220,6 +221,15 @@ export function setTransformData(pluginName: string, value: any) { } export function transformHook(originalCode: string, filename: string, moduleUrl?: string): { code: string, serializedCache?: any } { + // TODO: ideally, we would not transform before checking the cache. However, the source + // currently depends on the seed.md, so "originalCode" is not enough to produce a cache key. + let inputSourceMap: EncodedSourceMap | undefined; + if (filename.endsWith('.md')) { + const transformed = transformMDToTS(originalCode, filename); + originalCode = transformed.code; + inputSourceMap = transformed.map; + } + const hasPreprocessor = process.env.PW_TEST_SOURCE_TRANSFORM && process.env.PW_TEST_SOURCE_TRANSFORM_SCOPE && @@ -237,7 +247,7 @@ export function transformHook(originalCode: string, filename: string, moduleUrl? const { babelTransform }: { babelTransform: BabelTransformFunction } = require('./babelBundle'); transformData = new Map(); - const babelResult = babelTransform(originalCode, filename, !!moduleUrl, pluginsPrologue, pluginsEpilogue); + const babelResult = babelTransform(originalCode, filename, !!moduleUrl, pluginsPrologue, pluginsEpilogue, inputSourceMap); if (!babelResult?.code) return { code: originalCode, serializedCache }; const { code, map } = babelResult; @@ -308,7 +318,7 @@ function installTransformIfNeeded() { // Hopefully, one day we can migrate to synchronous loader hooks instead, similar to our esmLoader... addHook((code, filename) => { return transformHook(code, filename).code; - }, shouldTransform, ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.mts', '.cjs', '.cts']); + }, shouldTransform, ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.mts', '.cjs', '.cts', '.md']); } const collectCJSDependencies = (module: Module, dependencies: Set) => { diff --git a/packages/playwright/src/utilsBundle.ts b/packages/playwright/src/utilsBundle.ts index 1e61ccc5cae41..91e54162e5f74 100644 --- a/packages/playwright/src/utilsBundle.ts +++ b/packages/playwright/src/utilsBundle.ts @@ -21,3 +21,9 @@ export const enquirer: typeof import('../bundles/utils/node_modules/enquirer') = export const chokidar: typeof import('../bundles/utils/node_modules/chokidar') = require('./utilsBundleImpl').chokidar; export const getEastAsianWidth: typeof import('../bundles/utils/node_modules/get-east-asian-width') = require('./utilsBundleImpl').getEastAsianWidth; export type { RawSourceMap } from '../bundles/utils/node_modules/source-map'; + +const { unified } = require('./utilsBundleImpl').unified; +const remarkParse = require('./utilsBundleImpl').remarkParse; +export function parseMarkdown(content: string): import('mdast').Root { + return unified().use(remarkParse).parse(content); +} diff --git a/packages/playwright/src/worker/testInfo.ts b/packages/playwright/src/worker/testInfo.ts index 4d99313c05c1a..db8a4d6e2ec5e 100644 --- a/packages/playwright/src/worker/testInfo.ts +++ b/packages/playwright/src/worker/testInfo.ts @@ -474,7 +474,7 @@ export class TestInfoImpl implements TestInfo { const shouldPause = (this._workerParams.pauseAtEnd && !this._isFailure()) || (this._workerParams.pauseOnError && this._isFailure()); if (shouldPause) { await Promise.race([ - this._callbacks.onTestPaused({ testId: this.testId, errors: this._isFailure() ? this.errors : [] }), + this._callbacks.onTestPaused({ testId: this.testId, errors: this._isFailure() ? this.errors : [], status: this.status }), this._interruptedPromise, ]); } diff --git a/packages/trace-viewer/src/ui/actionList.tsx b/packages/trace-viewer/src/ui/actionList.tsx index 879397d9ef289..08c2977169a53 100644 --- a/packages/trace-viewer/src/ui/actionList.tsx +++ b/packages/trace-viewer/src/ui/actionList.tsx @@ -152,7 +152,8 @@ export const renderAction = ( }; export function renderTitleForCall(action: ActionTraceEvent): { elements: React.ReactNode[], title: string } { - const titleFormat = action.title ?? methodMetainfo.get(action.class + '.' + action.method)?.title ?? action.method; + let titleFormat = action.title ?? methodMetainfo.get(action.class + '.' + action.method)?.title ?? action.method; + titleFormat = titleFormat.replace(/\n/g, ' '); const elements: React.ReactNode[] = []; const title: string[] = []; diff --git a/packages/trace-viewer/src/ui/sourceTab.tsx b/packages/trace-viewer/src/ui/sourceTab.tsx index 3b01c4fb7914c..4cbca74d0cf23 100644 --- a/packages/trace-viewer/src/ui/sourceTab.tsx +++ b/packages/trace-viewer/src/ui/sourceTab.tsx @@ -103,6 +103,7 @@ export const SourceTab: React.FunctionComponent<{ const showStackFrames = (stack?.length ?? 0) > 1; const shortFileName = getFileName(fileName); + const highligter = shortFileName.endsWith('.md') ? 'markdown' : 'javascript'; return {location && } } - + } sidebar={} />; diff --git a/tests/playwright-test/pause-at-end.spec.ts b/tests/playwright-test/pause-at-end.spec.ts index 6e47a38fa3f0c..60f27758640ae 100644 --- a/tests/playwright-test/pause-at-end.spec.ts +++ b/tests/playwright-test/pause-at-end.spec.ts @@ -79,7 +79,7 @@ test('--debug should pause at end', async ({ runInlineTest }) => { console.log('%%teardown'); }); ` - }, { debug: true }); + }, { pause: true }); expect(result.outputLines).toEqual([ 'onTestPaused at end', 'teardown', @@ -110,7 +110,7 @@ test('--debug should pause at end with setup project', async ({ runInlineTest }) console.log('main test started'); }); ` - }, { debug: true }); + }, { pause: true }); expect(result.outputLines).toContain('onTestPaused at end'); }); @@ -128,7 +128,7 @@ test('--debug should pause on error', async ({ runInlineTest, mergeReports }) => console.log('%%after error'); }); ` - }, { debug: true }); + }, { pause: true }); expect(result.outputLines).toEqual([ 'onTestPaused on error at :4:24', 'result.errors[0] at :4:24', @@ -159,7 +159,7 @@ test('SIGINT after pause at end should still run teardown', async ({ runInlineTe console.log('%%teardown'); }); ` - }, { debug: true }, { SIGINT_AFTER_PAUSE: '1' }); + }, { pause: true }, { SIGINT_AFTER_PAUSE: '1' }); expect(result.outputLines).toEqual([ 'onTestPaused at end', 'SIGINT', @@ -185,7 +185,7 @@ test('SIGINT after pause on error should still run teardown', async ({ runInline console.log('%%teardown'); }); ` - }, { debug: true }, { SIGINT_AFTER_PAUSE: '1' }); + }, { pause: true }, { SIGINT_AFTER_PAUSE: '1' }); expect(result.outputLines).toEqual([ 'onTestPaused on error at :4:19', 'result.errors[0] at :4:19', diff --git a/tests/playwright-test/reporter-line.spec.ts b/tests/playwright-test/reporter-line.spec.ts index cd6fc6a65c26a..43c42c7081963 100644 --- a/tests/playwright-test/reporter-line.spec.ts +++ b/tests/playwright-test/reporter-line.spec.ts @@ -15,7 +15,7 @@ */ import path from 'path'; -import { test, expect } from './playwright-test-fixtures'; +import { test, expect, stripAnsi } from './playwright-test-fixtures'; for (const useIntermediateMergeReport of [false, true] as const) { test.describe(`${useIntermediateMergeReport ? 'merged' : 'created'}`, () => { @@ -225,3 +225,151 @@ for (const useIntermediateMergeReport of [false, true] as const) { }); }); } + +test.describe('onTestPaused', () => { + test.skip(process.platform === 'win32', 'No SIGINT on windows'); + + test('pause at end', async ({ interactWithTestRunner }) => { + const runner = await interactWithTestRunner({ + 'a.test.ts': ` + import { test, expect } from '@playwright/test'; + test('foo', async ({}) => { + }); + + test.afterEach(() => { + console.log('Running teardown'); + }); + `, + }, { pause: true, reporter: 'line' }, { PW_TEST_DEBUG_REPORTERS: '1' }); + + await runner.waitForOutput('Paused at test end. Press Ctrl+C to end.'); + const { exitCode } = await runner.kill('SIGINT'); + expect(exitCode).toBe(130); + + expect(stripAnsi(runner.output)).toEqual(` +Running 1 test using 1 worker + +[1/1] a.test.ts:3:13 › foo + a.test.ts:3:13 › foo ───────────────────────────────────────────────────────────────────────────── + Paused at test end. Press Ctrl+C to end. + + +[1/1] a.test.ts:3:13 › foo +a.test.ts:3:13 › foo +Running teardown + + 1) a.test.ts:3:13 › foo ────────────────────────────────────────────────────────────────────────── + + Test was interrupted. + + + 1 interrupted + a.test.ts:3:13 › foo ─────────────────────────────────────────────────────────────────────────── +`); + }); + + test('pause at end - error in teardown', async ({ interactWithTestRunner }) => { + const runner = await interactWithTestRunner({ + 'a.test.ts': ` + import { test, expect } from '@playwright/test'; + test('foo', async ({}) => { + }); + + test.afterEach(() => { + throw new Error('teardown error'); + }); + `, + }, { pause: true, reporter: 'line' }, { PW_TEST_DEBUG_REPORTERS: '1' }); + + await runner.waitForOutput('Paused at test end. Press Ctrl+C to end.'); + const { exitCode } = await runner.kill('SIGINT'); + expect(exitCode).toBe(130); + + expect(stripAnsi(runner.output)).toEqual(` +Running 1 test using 1 worker + +[1/1] a.test.ts:3:13 › foo + a.test.ts:3:13 › foo ───────────────────────────────────────────────────────────────────────────── + Paused at test end. Press Ctrl+C to end. + + +[1/1] a.test.ts:3:13 › foo + 1) a.test.ts:3:13 › foo ────────────────────────────────────────────────────────────────────────── + + Test was interrupted. + + Error: teardown error + + 5 | + 6 | test.afterEach(() => { + > 7 | throw new Error('teardown error'); + | ^ + 8 | }); + 9 | + at ${test.info().outputPath('a.test.ts')}:7:17 + + + 1 interrupted + a.test.ts:3:13 › foo ─────────────────────────────────────────────────────────────────────────── +`); + }); + + test('pause on error', async ({ interactWithTestRunner }) => { + const runner = await interactWithTestRunner({ + 'a.test.ts': ` + import { test, expect } from '@playwright/test'; + test('fails', async ({}) => { + expect.soft(2).toBe(3); + expect(3).toBe(4); + }); + `, + }, { pause: true, reporter: 'line' }, { PW_TEST_DEBUG_REPORTERS: '1' }); + + await runner.waitForOutput('Paused on error. Press Ctrl+C to end.'); + const { exitCode } = await runner.kill('SIGINT'); + expect(exitCode).toBe(130); + + expect(stripAnsi(runner.output)).toEqual(` +Running 1 test using 1 worker + +[1/1] a.test.ts:3:13 › fails + 1) a.test.ts:3:13 › fails ──────────────────────────────────────────────────────────────────────── + + Error: expect(received).toBe(expected) // Object.is equality + + Expected: 3 + Received: 2 + + 2 | import { test, expect } from '@playwright/test'; + 3 | test('fails', async ({}) => { + > 4 | expect.soft(2).toBe(3); + | ^ + 5 | expect(3).toBe(4); + 6 | }); + 7 | + at ${test.info().outputPath('a.test.ts')}:4:26 + + Error: expect(received).toBe(expected) // Object.is equality + + Expected: 4 + Received: 3 + + 3 | test('fails', async ({}) => { + 4 | expect.soft(2).toBe(3); + > 5 | expect(3).toBe(4); + | ^ + 6 | }); + 7 | + at ${test.info().outputPath('a.test.ts')}:5:21 + + Paused on error. Press Ctrl+C to end. + + +[1/1] a.test.ts:3:13 › fails + + + 1 failed + a.test.ts:3:13 › fails ───────────────────────────────────────────────────────────────────────── +`); + }); +});