chore(codegen): move action update into the recorder app (#36523)
infra / docs & lint (push) Waiting to run
Details
infra / Lint snippets (push) Waiting to run
Details
components / ${{ matrix.os }} - Node.js ${{ matrix.node-version }} (18, macos-latest) (push) Waiting to run
Details
components / ${{ matrix.os }} - Node.js ${{ matrix.node-version }} (18, ubuntu-latest) (push) Waiting to run
Details
components / ${{ matrix.os }} - Node.js ${{ matrix.node-version }} (18, windows-latest) (push) Waiting to run
Details
components / ${{ matrix.os }} - Node.js ${{ matrix.node-version }} (20, ubuntu-latest) (push) Waiting to run
Details
components / ${{ matrix.os }} - Node.js ${{ matrix.node-version }} (22, ubuntu-latest) (push) Waiting to run
Details
tests others / Stress - ${{ matrix.os }} (macos-latest) (push) Waiting to run
Details
tests others / Stress - ${{ matrix.os }} (ubuntu-latest) (push) Waiting to run
Details
tests others / Stress - ${{ matrix.os }} (windows-latest) (push) Waiting to run
Details
tests others / WebView2 (push) Waiting to run
Details
tests others / time library - ${{ matrix.clock }} (frozen) (push) Waiting to run
Details
tests others / time library - ${{ matrix.clock }} (realtime) (push) Waiting to run
Details
tests others / time test runner - ${{ matrix.clock }} (frozen) (push) Waiting to run
Details
tests others / time test runner - ${{ matrix.clock }} (realtime) (push) Waiting to run
Details
tests others / legacy progress timeouts (push) Waiting to run
Details
tests others / Electron - ${{ matrix.os }} (macos-latest) (push) Waiting to run
Details
tests others / Electron - ${{ matrix.os }} (ubuntu-latest) (push) Waiting to run
Details
tests others / Electron - ${{ matrix.os }} (windows-latest) (push) Waiting to run
Details
tests 1 / ${{ matrix.os }} (${{ matrix.browser }} - Node.js ${{ matrix.node-version }}) (chromium, 18, ubuntu-22.04) (push) Waiting to run
Details
tests 1 / ${{ matrix.os }} (${{ matrix.browser }} - Node.js ${{ matrix.node-version }}) (chromium, 20, ubuntu-22.04) (push) Waiting to run
Details
tests 1 / ${{ matrix.os }} (${{ matrix.browser }} - Node.js ${{ matrix.node-version }}) (chromium, 22, ubuntu-22.04) (push) Waiting to run
Details
tests 1 / ${{ matrix.os }} (${{ matrix.browser }} - Node.js ${{ matrix.node-version }}) (chromium, 24, ubuntu-22.04) (push) Waiting to run
Details
tests 1 / ${{ matrix.os }} (${{ matrix.browser }} - Node.js ${{ matrix.node-version }}) (firefox, 18, ubuntu-22.04) (push) Waiting to run
Details
tests 1 / ${{ matrix.os }} (${{ matrix.browser }} - Node.js ${{ matrix.node-version }}) (webkit, 18, ubuntu-22.04) (push) Waiting to run
Details
tests 1 / ${{ matrix.os }} (chromium tip-of-tree) (ubuntu-22.04) (push) Waiting to run
Details
tests 1 / Test Runner (18, macos-latest, 1, 2) (push) Waiting to run
Details
tests 1 / Test Runner (18, macos-latest, 2, 2) (push) Waiting to run
Details
tests 1 / Test Runner (18, ubuntu-latest, 1, 2) (push) Waiting to run
Details
tests 1 / Test Runner (18, ubuntu-latest, 2, 2) (push) Waiting to run
Details
tests 1 / Test Runner (18, windows-latest, 1, 2) (push) Waiting to run
Details
tests 1 / Test Runner (18, windows-latest, 2, 2) (push) Waiting to run
Details
tests 1 / Test Runner (20, ubuntu-latest, 1, 2) (push) Waiting to run
Details
tests 1 / Test Runner (20, ubuntu-latest, 2, 2) (push) Waiting to run
Details
tests 1 / Test Runner (22, ubuntu-latest, 1, 2) (push) Waiting to run
Details
tests 1 / Test Runner (22, ubuntu-latest, 2, 2) (push) Waiting to run
Details
tests 1 / Test Runner (24, ubuntu-latest, 1, 2) (push) Waiting to run
Details
tests 1 / Test Runner (24, ubuntu-latest, 2, 2) (push) Waiting to run
Details
tests 1 / Web Components (push) Waiting to run
Details
tests 1 / VSCode Extension (push) Waiting to run
Details
tests 1 / Installation Test ${{ matrix.os }} (macos-latest) (push) Waiting to run
Details
tests 1 / Installation Test ${{ matrix.os }} (ubuntu-latest) (push) Waiting to run
Details
tests 1 / Installation Test ${{ matrix.os }} (windows-latest) (push) Waiting to run
Details
tests 2 / ${{ matrix.os }} (${{ matrix.browser }}) (chromium, ubuntu-24.04) (push) Waiting to run
Details
tests 2 / ${{ matrix.os }} (${{ matrix.browser }}) (firefox, ubuntu-24.04) (push) Waiting to run
Details
tests 2 / ${{ matrix.os }} (${{ matrix.browser }}) (webkit, ubuntu-24.04) (push) Waiting to run
Details
tests 2 / ${{ matrix.os }} (${{ matrix.browser }}) (chromium, macos-13-large) (push) Waiting to run
Details
tests 2 / ${{ matrix.os }} (${{ matrix.browser }}) (chromium, macos-13-xlarge) (push) Waiting to run
Details
tests 2 / ${{ matrix.os }} (${{ matrix.browser }}) (chromium, macos-14-large) (push) Waiting to run
Details
tests 2 / ${{ matrix.os }} (${{ matrix.browser }}) (chromium, macos-14-xlarge) (push) Waiting to run
Details
tests 2 / ${{ matrix.os }} (${{ matrix.browser }}) (firefox, macos-13-large) (push) Waiting to run
Details
tests 2 / ${{ matrix.os }} (${{ matrix.browser }}) (firefox, macos-13-xlarge) (push) Waiting to run
Details
tests 2 / ${{ matrix.os }} (${{ matrix.browser }}) (firefox, macos-14-large) (push) Waiting to run
Details
tests 2 / ${{ matrix.os }} (${{ matrix.browser }}) (firefox, macos-14-xlarge) (push) Waiting to run
Details
tests 2 / ${{ matrix.os }} (${{ matrix.browser }}) (webkit, macos-13-large) (push) Waiting to run
Details
tests 2 / ${{ matrix.os }} (${{ matrix.browser }}) (webkit, macos-13-xlarge) (push) Waiting to run
Details
tests 2 / ${{ matrix.os }} (${{ matrix.browser }}) (webkit, macos-14-large) (push) Waiting to run
Details
tests 2 / ${{ matrix.os }} (${{ matrix.browser }}) (webkit, macos-14-xlarge) (push) Waiting to run
Details
tests 2 / ${{ matrix.os }} (${{ matrix.browser }}) (webkit, macos-15-large) (push) Waiting to run
Details
tests 2 / ${{ matrix.os }} (${{ matrix.browser }}) (webkit, macos-15-xlarge) (push) Waiting to run
Details
tests 2 / Windows (chromium) (push) Waiting to run
Details
tests 2 / Windows (firefox) (push) Waiting to run
Details
tests 2 / Windows (webkit) (push) Waiting to run
Details
tests 2 / Installation Test ${{ matrix.os }} (${{ matrix.node_version }}) (20, ubuntu-latest) (push) Waiting to run
Details
tests 2 / Installation Test ${{ matrix.os }} (${{ matrix.node_version }}) (22, ubuntu-latest) (push) Waiting to run
Details
tests 2 / Installation Test ${{ matrix.os }} (${{ matrix.node_version }}) (24, ubuntu-latest) (push) Waiting to run
Details
tests 2 / headed ${{ matrix.browser }} (${{ matrix.os }}) (chromium, macos-14-xlarge) (push) Waiting to run
Details
tests 2 / headed ${{ matrix.browser }} (${{ matrix.os }}) (chromium, ubuntu-24.04) (push) Waiting to run
Details
tests 2 / headed ${{ matrix.browser }} (${{ matrix.os }}) (chromium, windows-latest) (push) Waiting to run
Details
tests 2 / headed ${{ matrix.browser }} (${{ matrix.os }}) (firefox, macos-14-xlarge) (push) Waiting to run
Details
tests 2 / headed ${{ matrix.browser }} (${{ matrix.os }}) (firefox, ubuntu-24.04) (push) Waiting to run
Details
tests 2 / headed ${{ matrix.browser }} (${{ matrix.os }}) (firefox, windows-latest) (push) Waiting to run
Details
tests 2 / headed ${{ matrix.browser }} (${{ matrix.os }}) (webkit, macos-14-xlarge) (push) Waiting to run
Details
tests 2 / headed ${{ matrix.browser }} (${{ matrix.os }}) (webkit, ubuntu-22.04) (push) Waiting to run
Details
tests 2 / headed ${{ matrix.browser }} (${{ matrix.os }}) (webkit, ubuntu-24.04) (push) Waiting to run
Details
tests 2 / headed ${{ matrix.browser }} (${{ matrix.os }}) (webkit, windows-latest) (push) Waiting to run
Details
tests 2 / Transport (driver) (push) Waiting to run
Details
tests 2 / Transport (service) (push) Waiting to run
Details
tests 2 / Tracing ${{ matrix.browser }} ${{ matrix.channel }} (chromium, chromium-tip-of-tree, ubuntu-22.04) (push) Waiting to run
Details
tests 2 / Tracing ${{ matrix.browser }} ${{ matrix.channel }} (chromium, ubuntu-22.04) (push) Waiting to run
Details
tests 2 / Tracing ${{ matrix.browser }} ${{ matrix.channel }} (firefox, ubuntu-22.04) (push) Waiting to run
Details
tests 2 / Tracing ${{ matrix.browser }} ${{ matrix.channel }} (webkit, ubuntu-24.04) (push) Waiting to run
Details
tests 2 / Test ${{ matrix.channel }} on ${{ matrix.runs-on }} (chrome, macos-latest) (push) Waiting to run
Details
tests 2 / Test ${{ matrix.channel }} on ${{ matrix.runs-on }} (chrome, ubuntu-22.04) (push) Waiting to run
Details
tests 2 / Test ${{ matrix.channel }} on ${{ matrix.runs-on }} (chrome, windows-latest) (push) Waiting to run
Details
tests 2 / Test ${{ matrix.channel }} on ${{ matrix.runs-on }} (chrome-beta, macos-latest) (push) Waiting to run
Details
tests 2 / Test ${{ matrix.channel }} on ${{ matrix.runs-on }} (chrome-beta, ubuntu-22.04) (push) Waiting to run
Details
tests 2 / Test ${{ matrix.channel }} on ${{ matrix.runs-on }} (chrome-beta, windows-latest) (push) Waiting to run
Details
tests 2 / Test ${{ matrix.channel }} on ${{ matrix.runs-on }} (msedge, macos-latest) (push) Waiting to run
Details
tests 2 / Test ${{ matrix.channel }} on ${{ matrix.runs-on }} (msedge, ubuntu-22.04) (push) Waiting to run
Details
tests 2 / Test ${{ matrix.channel }} on ${{ matrix.runs-on }} (msedge, windows-latest) (push) Waiting to run
Details
tests 2 / Test ${{ matrix.channel }} on ${{ matrix.runs-on }} (msedge-beta, macos-latest) (push) Waiting to run
Details
tests 2 / Test ${{ matrix.channel }} on ${{ matrix.runs-on }} (msedge-beta, ubuntu-22.04) (push) Waiting to run
Details
tests 2 / Test ${{ matrix.channel }} on ${{ matrix.runs-on }} (msedge-beta, windows-latest) (push) Waiting to run
Details
tests 2 / Test ${{ matrix.channel }} on ${{ matrix.runs-on }} (msedge-dev, macos-latest) (push) Waiting to run
Details
tests 2 / Test ${{ matrix.channel }} on ${{ matrix.runs-on }} (msedge-dev, ubuntu-22.04) (push) Waiting to run
Details
tests 2 / Test ${{ matrix.channel }} on ${{ matrix.runs-on }} (msedge-dev, windows-latest) (push) Waiting to run
Details
tests 2 / Chromium tip-of-tree ${{ matrix.os }}${{ matrix.headed }} (, macos-13) (push) Waiting to run
Details
tests 2 / Chromium tip-of-tree ${{ matrix.os }}${{ matrix.headed }} (, windows-latest) (push) Waiting to run
Details
tests 2 / Chromium tip-of-tree ${{ matrix.os }}${{ matrix.headed }} (--headed, macos-13) (push) Waiting to run
Details
tests 2 / Chromium tip-of-tree ${{ matrix.os }}${{ matrix.headed }} (--headed, ubuntu-22.04) (push) Waiting to run
Details
tests 2 / Chromium tip-of-tree ${{ matrix.os }}${{ matrix.headed }} (--headed, windows-latest) (push) Waiting to run
Details
tests 2 / Chromium tip-of-tree headless-shell-${{ matrix.os }} (ubuntu-22.04) (push) Waiting to run
Details
tests 2 / Firefox Beta ${{ matrix.os }} (macos-latest) (push) Waiting to run
Details
tests 2 / Firefox Beta ${{ matrix.os }} (ubuntu-22.04) (push) Waiting to run
Details
tests 2 / Firefox Beta ${{ matrix.os }} (windows-latest) (push) Waiting to run
Details
tests 2 / build-playwright-driver (push) Waiting to run
Details
tests 2 / Test channel=chromium (macos-latest) (push) Waiting to run
Details
tests 2 / Test channel=chromium (ubuntu-latest) (push) Waiting to run
Details
tests 2 / Test channel=chromium (windows-latest) (push) Waiting to run
Details
tests Video / Video Linux (chromium, ubuntu-22.04) (push) Waiting to run
Details
tests Video / Video Linux (chromium, ubuntu-24.04) (push) Waiting to run
Details
tests Video / Video Linux (firefox, ubuntu-22.04) (push) Waiting to run
Details
tests Video / Video Linux (firefox, ubuntu-24.04) (push) Waiting to run
Details
tests Video / Video Linux (webkit, ubuntu-22.04) (push) Waiting to run
Details
tests Video / Video Linux (webkit, ubuntu-24.04) (push) Waiting to run
Details
Internal Tests / trigger (push) Waiting to run
Details
infra / docs & lint (push) Waiting to run
Details
infra / Lint snippets (push) Waiting to run
Details
components / ${{ matrix.os }} - Node.js ${{ matrix.node-version }} (18, macos-latest) (push) Waiting to run
Details
components / ${{ matrix.os }} - Node.js ${{ matrix.node-version }} (18, ubuntu-latest) (push) Waiting to run
Details
components / ${{ matrix.os }} - Node.js ${{ matrix.node-version }} (18, windows-latest) (push) Waiting to run
Details
components / ${{ matrix.os }} - Node.js ${{ matrix.node-version }} (20, ubuntu-latest) (push) Waiting to run
Details
components / ${{ matrix.os }} - Node.js ${{ matrix.node-version }} (22, ubuntu-latest) (push) Waiting to run
Details
tests others / Stress - ${{ matrix.os }} (macos-latest) (push) Waiting to run
Details
tests others / Stress - ${{ matrix.os }} (ubuntu-latest) (push) Waiting to run
Details
tests others / Stress - ${{ matrix.os }} (windows-latest) (push) Waiting to run
Details
tests others / WebView2 (push) Waiting to run
Details
tests others / time library - ${{ matrix.clock }} (frozen) (push) Waiting to run
Details
tests others / time library - ${{ matrix.clock }} (realtime) (push) Waiting to run
Details
tests others / time test runner - ${{ matrix.clock }} (frozen) (push) Waiting to run
Details
tests others / time test runner - ${{ matrix.clock }} (realtime) (push) Waiting to run
Details
tests others / legacy progress timeouts (push) Waiting to run
Details
tests others / Electron - ${{ matrix.os }} (macos-latest) (push) Waiting to run
Details
tests others / Electron - ${{ matrix.os }} (ubuntu-latest) (push) Waiting to run
Details
tests others / Electron - ${{ matrix.os }} (windows-latest) (push) Waiting to run
Details
tests 1 / ${{ matrix.os }} (${{ matrix.browser }} - Node.js ${{ matrix.node-version }}) (chromium, 18, ubuntu-22.04) (push) Waiting to run
Details
tests 1 / ${{ matrix.os }} (${{ matrix.browser }} - Node.js ${{ matrix.node-version }}) (chromium, 20, ubuntu-22.04) (push) Waiting to run
Details
tests 1 / ${{ matrix.os }} (${{ matrix.browser }} - Node.js ${{ matrix.node-version }}) (chromium, 22, ubuntu-22.04) (push) Waiting to run
Details
tests 1 / ${{ matrix.os }} (${{ matrix.browser }} - Node.js ${{ matrix.node-version }}) (chromium, 24, ubuntu-22.04) (push) Waiting to run
Details
tests 1 / ${{ matrix.os }} (${{ matrix.browser }} - Node.js ${{ matrix.node-version }}) (firefox, 18, ubuntu-22.04) (push) Waiting to run
Details
tests 1 / ${{ matrix.os }} (${{ matrix.browser }} - Node.js ${{ matrix.node-version }}) (webkit, 18, ubuntu-22.04) (push) Waiting to run
Details
tests 1 / ${{ matrix.os }} (chromium tip-of-tree) (ubuntu-22.04) (push) Waiting to run
Details
tests 1 / Test Runner (18, macos-latest, 1, 2) (push) Waiting to run
Details
tests 1 / Test Runner (18, macos-latest, 2, 2) (push) Waiting to run
Details
tests 1 / Test Runner (18, ubuntu-latest, 1, 2) (push) Waiting to run
Details
tests 1 / Test Runner (18, ubuntu-latest, 2, 2) (push) Waiting to run
Details
tests 1 / Test Runner (18, windows-latest, 1, 2) (push) Waiting to run
Details
tests 1 / Test Runner (18, windows-latest, 2, 2) (push) Waiting to run
Details
tests 1 / Test Runner (20, ubuntu-latest, 1, 2) (push) Waiting to run
Details
tests 1 / Test Runner (20, ubuntu-latest, 2, 2) (push) Waiting to run
Details
tests 1 / Test Runner (22, ubuntu-latest, 1, 2) (push) Waiting to run
Details
tests 1 / Test Runner (22, ubuntu-latest, 2, 2) (push) Waiting to run
Details
tests 1 / Test Runner (24, ubuntu-latest, 1, 2) (push) Waiting to run
Details
tests 1 / Test Runner (24, ubuntu-latest, 2, 2) (push) Waiting to run
Details
tests 1 / Web Components (push) Waiting to run
Details
tests 1 / VSCode Extension (push) Waiting to run
Details
tests 1 / Installation Test ${{ matrix.os }} (macos-latest) (push) Waiting to run
Details
tests 1 / Installation Test ${{ matrix.os }} (ubuntu-latest) (push) Waiting to run
Details
tests 1 / Installation Test ${{ matrix.os }} (windows-latest) (push) Waiting to run
Details
tests 2 / ${{ matrix.os }} (${{ matrix.browser }}) (chromium, ubuntu-24.04) (push) Waiting to run
Details
tests 2 / ${{ matrix.os }} (${{ matrix.browser }}) (firefox, ubuntu-24.04) (push) Waiting to run
Details
tests 2 / ${{ matrix.os }} (${{ matrix.browser }}) (webkit, ubuntu-24.04) (push) Waiting to run
Details
tests 2 / ${{ matrix.os }} (${{ matrix.browser }}) (chromium, macos-13-large) (push) Waiting to run
Details
tests 2 / ${{ matrix.os }} (${{ matrix.browser }}) (chromium, macos-13-xlarge) (push) Waiting to run
Details
tests 2 / ${{ matrix.os }} (${{ matrix.browser }}) (chromium, macos-14-large) (push) Waiting to run
Details
tests 2 / ${{ matrix.os }} (${{ matrix.browser }}) (chromium, macos-14-xlarge) (push) Waiting to run
Details
tests 2 / ${{ matrix.os }} (${{ matrix.browser }}) (firefox, macos-13-large) (push) Waiting to run
Details
tests 2 / ${{ matrix.os }} (${{ matrix.browser }}) (firefox, macos-13-xlarge) (push) Waiting to run
Details
tests 2 / ${{ matrix.os }} (${{ matrix.browser }}) (firefox, macos-14-large) (push) Waiting to run
Details
tests 2 / ${{ matrix.os }} (${{ matrix.browser }}) (firefox, macos-14-xlarge) (push) Waiting to run
Details
tests 2 / ${{ matrix.os }} (${{ matrix.browser }}) (webkit, macos-13-large) (push) Waiting to run
Details
tests 2 / ${{ matrix.os }} (${{ matrix.browser }}) (webkit, macos-13-xlarge) (push) Waiting to run
Details
tests 2 / ${{ matrix.os }} (${{ matrix.browser }}) (webkit, macos-14-large) (push) Waiting to run
Details
tests 2 / ${{ matrix.os }} (${{ matrix.browser }}) (webkit, macos-14-xlarge) (push) Waiting to run
Details
tests 2 / ${{ matrix.os }} (${{ matrix.browser }}) (webkit, macos-15-large) (push) Waiting to run
Details
tests 2 / ${{ matrix.os }} (${{ matrix.browser }}) (webkit, macos-15-xlarge) (push) Waiting to run
Details
tests 2 / Windows (chromium) (push) Waiting to run
Details
tests 2 / Windows (firefox) (push) Waiting to run
Details
tests 2 / Windows (webkit) (push) Waiting to run
Details
tests 2 / Installation Test ${{ matrix.os }} (${{ matrix.node_version }}) (20, ubuntu-latest) (push) Waiting to run
Details
tests 2 / Installation Test ${{ matrix.os }} (${{ matrix.node_version }}) (22, ubuntu-latest) (push) Waiting to run
Details
tests 2 / Installation Test ${{ matrix.os }} (${{ matrix.node_version }}) (24, ubuntu-latest) (push) Waiting to run
Details
tests 2 / headed ${{ matrix.browser }} (${{ matrix.os }}) (chromium, macos-14-xlarge) (push) Waiting to run
Details
tests 2 / headed ${{ matrix.browser }} (${{ matrix.os }}) (chromium, ubuntu-24.04) (push) Waiting to run
Details
tests 2 / headed ${{ matrix.browser }} (${{ matrix.os }}) (chromium, windows-latest) (push) Waiting to run
Details
tests 2 / headed ${{ matrix.browser }} (${{ matrix.os }}) (firefox, macos-14-xlarge) (push) Waiting to run
Details
tests 2 / headed ${{ matrix.browser }} (${{ matrix.os }}) (firefox, ubuntu-24.04) (push) Waiting to run
Details
tests 2 / headed ${{ matrix.browser }} (${{ matrix.os }}) (firefox, windows-latest) (push) Waiting to run
Details
tests 2 / headed ${{ matrix.browser }} (${{ matrix.os }}) (webkit, macos-14-xlarge) (push) Waiting to run
Details
tests 2 / headed ${{ matrix.browser }} (${{ matrix.os }}) (webkit, ubuntu-22.04) (push) Waiting to run
Details
tests 2 / headed ${{ matrix.browser }} (${{ matrix.os }}) (webkit, ubuntu-24.04) (push) Waiting to run
Details
tests 2 / headed ${{ matrix.browser }} (${{ matrix.os }}) (webkit, windows-latest) (push) Waiting to run
Details
tests 2 / Transport (driver) (push) Waiting to run
Details
tests 2 / Transport (service) (push) Waiting to run
Details
tests 2 / Tracing ${{ matrix.browser }} ${{ matrix.channel }} (chromium, chromium-tip-of-tree, ubuntu-22.04) (push) Waiting to run
Details
tests 2 / Tracing ${{ matrix.browser }} ${{ matrix.channel }} (chromium, ubuntu-22.04) (push) Waiting to run
Details
tests 2 / Tracing ${{ matrix.browser }} ${{ matrix.channel }} (firefox, ubuntu-22.04) (push) Waiting to run
Details
tests 2 / Tracing ${{ matrix.browser }} ${{ matrix.channel }} (webkit, ubuntu-24.04) (push) Waiting to run
Details
tests 2 / Test ${{ matrix.channel }} on ${{ matrix.runs-on }} (chrome, macos-latest) (push) Waiting to run
Details
tests 2 / Test ${{ matrix.channel }} on ${{ matrix.runs-on }} (chrome, ubuntu-22.04) (push) Waiting to run
Details
tests 2 / Test ${{ matrix.channel }} on ${{ matrix.runs-on }} (chrome, windows-latest) (push) Waiting to run
Details
tests 2 / Test ${{ matrix.channel }} on ${{ matrix.runs-on }} (chrome-beta, macos-latest) (push) Waiting to run
Details
tests 2 / Test ${{ matrix.channel }} on ${{ matrix.runs-on }} (chrome-beta, ubuntu-22.04) (push) Waiting to run
Details
tests 2 / Test ${{ matrix.channel }} on ${{ matrix.runs-on }} (chrome-beta, windows-latest) (push) Waiting to run
Details
tests 2 / Test ${{ matrix.channel }} on ${{ matrix.runs-on }} (msedge, macos-latest) (push) Waiting to run
Details
tests 2 / Test ${{ matrix.channel }} on ${{ matrix.runs-on }} (msedge, ubuntu-22.04) (push) Waiting to run
Details
tests 2 / Test ${{ matrix.channel }} on ${{ matrix.runs-on }} (msedge, windows-latest) (push) Waiting to run
Details
tests 2 / Test ${{ matrix.channel }} on ${{ matrix.runs-on }} (msedge-beta, macos-latest) (push) Waiting to run
Details
tests 2 / Test ${{ matrix.channel }} on ${{ matrix.runs-on }} (msedge-beta, ubuntu-22.04) (push) Waiting to run
Details
tests 2 / Test ${{ matrix.channel }} on ${{ matrix.runs-on }} (msedge-beta, windows-latest) (push) Waiting to run
Details
tests 2 / Test ${{ matrix.channel }} on ${{ matrix.runs-on }} (msedge-dev, macos-latest) (push) Waiting to run
Details
tests 2 / Test ${{ matrix.channel }} on ${{ matrix.runs-on }} (msedge-dev, ubuntu-22.04) (push) Waiting to run
Details
tests 2 / Test ${{ matrix.channel }} on ${{ matrix.runs-on }} (msedge-dev, windows-latest) (push) Waiting to run
Details
tests 2 / Chromium tip-of-tree ${{ matrix.os }}${{ matrix.headed }} (, macos-13) (push) Waiting to run
Details
tests 2 / Chromium tip-of-tree ${{ matrix.os }}${{ matrix.headed }} (, windows-latest) (push) Waiting to run
Details
tests 2 / Chromium tip-of-tree ${{ matrix.os }}${{ matrix.headed }} (--headed, macos-13) (push) Waiting to run
Details
tests 2 / Chromium tip-of-tree ${{ matrix.os }}${{ matrix.headed }} (--headed, ubuntu-22.04) (push) Waiting to run
Details
tests 2 / Chromium tip-of-tree ${{ matrix.os }}${{ matrix.headed }} (--headed, windows-latest) (push) Waiting to run
Details
tests 2 / Chromium tip-of-tree headless-shell-${{ matrix.os }} (ubuntu-22.04) (push) Waiting to run
Details
tests 2 / Firefox Beta ${{ matrix.os }} (macos-latest) (push) Waiting to run
Details
tests 2 / Firefox Beta ${{ matrix.os }} (ubuntu-22.04) (push) Waiting to run
Details
tests 2 / Firefox Beta ${{ matrix.os }} (windows-latest) (push) Waiting to run
Details
tests 2 / build-playwright-driver (push) Waiting to run
Details
tests 2 / Test channel=chromium (macos-latest) (push) Waiting to run
Details
tests 2 / Test channel=chromium (ubuntu-latest) (push) Waiting to run
Details
tests 2 / Test channel=chromium (windows-latest) (push) Waiting to run
Details
tests Video / Video Linux (chromium, ubuntu-22.04) (push) Waiting to run
Details
tests Video / Video Linux (chromium, ubuntu-24.04) (push) Waiting to run
Details
tests Video / Video Linux (firefox, ubuntu-22.04) (push) Waiting to run
Details
tests Video / Video Linux (firefox, ubuntu-24.04) (push) Waiting to run
Details
tests Video / Video Linux (webkit, ubuntu-22.04) (push) Waiting to run
Details
tests Video / Video Linux (webkit, ubuntu-24.04) (push) Waiting to run
Details
Internal Tests / trigger (push) Waiting to run
Details
This commit is contained in:
parent
04d1c083b1
commit
fc0b770d0c
|
@ -71,7 +71,14 @@ commandWithOpenOptions('codegen [url]', 'open page and generate code for user ac
|
|||
['--target <language>', `language to generate, one of javascript, playwright-test, python, python-async, python-pytest, csharp, csharp-mstest, csharp-nunit, java, java-junit`, codegenId()],
|
||||
['--test-id-attribute <attributeName>', 'use the specified attribute to generate data test ID selectors'],
|
||||
]).action(function(url, options) {
|
||||
codegen(options, url).catch(logErrorAndExit);
|
||||
codegen(options, url).catch(error => {
|
||||
if (process.env.PWTEST_CLI_AUTO_EXIT_WHEN) {
|
||||
// Tests with PWTEST_CLI_AUTO_EXIT_WHEN might close page too fast, resulting
|
||||
// in a stray navigation aborted error. We should ignore it.
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
}).addHelpText('afterAll', `
|
||||
Examples:
|
||||
|
||||
|
@ -480,8 +487,12 @@ async function launchContext(options: Options, extraOptions: LaunchOptions): Pro
|
|||
process.stdout.write(text);
|
||||
process.stdout.write('\n-------------8<-------------\n');
|
||||
const autoExitCondition = process.env.PWTEST_CLI_AUTO_EXIT_WHEN;
|
||||
if (autoExitCondition && text.includes(autoExitCondition))
|
||||
if (autoExitCondition && text.includes(autoExitCondition)) {
|
||||
// Firefox needs a break here
|
||||
setTimeout(() => {
|
||||
closeBrowser();
|
||||
}, 1000);
|
||||
}
|
||||
};
|
||||
// Make sure we exit abnormally when browser crashes.
|
||||
const logs: string[] = [];
|
||||
|
@ -615,14 +626,7 @@ async function openPage(context: BrowserContext, url: string | undefined): Promi
|
|||
url = 'file://' + path.resolve(url);
|
||||
else if (!url.startsWith('http') && !url.startsWith('file://') && !url.startsWith('about:') && !url.startsWith('data:'))
|
||||
url = 'http://' + url;
|
||||
await page.goto(url).catch(error => {
|
||||
if (process.env.PWTEST_CLI_AUTO_EXIT_WHEN) {
|
||||
// Tests with PWTEST_CLI_AUTO_EXIT_WHEN might close page too fast, resulting
|
||||
// in a stray navigation aborted error. We should ignore it.
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
await page.goto(url);
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
../utilsBundle.ts
|
||||
../zipBundle.ts
|
||||
./
|
||||
./codegen/language.ts
|
||||
./codegen/languages.ts
|
||||
./codegen/
|
||||
./isomorphic/
|
||||
./har/
|
||||
./recorder/
|
||||
|
|
|
@ -31,7 +31,6 @@ import { SdkObject } from './instrumentation';
|
|||
import * as network from './network';
|
||||
import { InitScript } from './page';
|
||||
import { Page, PageBinding } from './page';
|
||||
import { Recorder } from './recorder';
|
||||
import { RecorderApp } from './recorder/recorderApp';
|
||||
import { Selectors } from './selectors';
|
||||
import { Tracing } from './trace/recorder/tracing';
|
||||
|
@ -129,15 +128,15 @@ export abstract class BrowserContext extends SdkObject {
|
|||
|
||||
// When PWDEBUG=1, show inspector for each context.
|
||||
if (debugMode() === 'inspector')
|
||||
await Recorder.show(this, RecorderApp.factory(this), { pauseOnNextStatement: true });
|
||||
await RecorderApp.show(this, { pauseOnNextStatement: true });
|
||||
|
||||
// When paused, show inspector.
|
||||
if (this._debugger.isPaused())
|
||||
Recorder.showInspectorNoReply(this, RecorderApp.factory(this));
|
||||
await RecorderApp.showInspectorNoReply(this);
|
||||
|
||||
this._debugger.on(Debugger.Events.PausedStateChanged, () => {
|
||||
if (this._debugger.isPaused())
|
||||
Recorder.showInspectorNoReply(this, RecorderApp.factory(this));
|
||||
RecorderApp.showInspectorNoReply(this);
|
||||
});
|
||||
|
||||
if (debugMode() === 'console')
|
||||
|
|
|
@ -22,16 +22,16 @@ import { PythonLanguageGenerator } from './python';
|
|||
|
||||
export function languageSet() {
|
||||
return new Set([
|
||||
new JavaLanguageGenerator('junit'),
|
||||
new JavaLanguageGenerator('library'),
|
||||
new JavaScriptLanguageGenerator(/* isPlaywrightTest */false),
|
||||
new JavaScriptLanguageGenerator(/* isPlaywrightTest */true),
|
||||
new JavaScriptLanguageGenerator(/* isPlaywrightTest */false),
|
||||
new PythonLanguageGenerator(/* isAsync */false, /* isPytest */true),
|
||||
new PythonLanguageGenerator(/* isAsync */false, /* isPytest */false),
|
||||
new PythonLanguageGenerator(/* isAsync */true, /* isPytest */false),
|
||||
new CSharpLanguageGenerator('mstest'),
|
||||
new CSharpLanguageGenerator('nunit'),
|
||||
new CSharpLanguageGenerator('library'),
|
||||
new JavaLanguageGenerator('junit'),
|
||||
new JavaLanguageGenerator('library'),
|
||||
new JsonlLanguageGenerator(),
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -22,14 +22,18 @@ import { parseAriaSnapshotUnsafe } from '../utils/isomorphic/ariaSnapshot';
|
|||
import { yaml } from '../utilsBundle';
|
||||
import { EmptyRecorderApp } from './recorder/recorderApp';
|
||||
import { unsafeLocatorOrSelectorAsSelector } from '../utils/isomorphic/locatorParser';
|
||||
import { generateCode } from './codegen/language';
|
||||
import { collapseActions } from './recorder/recorderUtils';
|
||||
import { JavaScriptLanguageGenerator } from './codegen/javascript';
|
||||
|
||||
import type { Language } from '../utils';
|
||||
import type { Browser } from './browser';
|
||||
import type { BrowserContext } from './browserContext';
|
||||
import type { InstrumentationListener } from './instrumentation';
|
||||
import type { Playwright } from './playwright';
|
||||
import type { ElementInfo, Mode, Source } from '@recorder/recorderTypes';
|
||||
import type { ElementInfo, Mode } from '@recorder/recorderTypes';
|
||||
import type { Progress } from '@protocol/progress';
|
||||
import type * as actions from '@recorder/actions';
|
||||
|
||||
export class DebugController extends SdkObject {
|
||||
static Events = {
|
||||
|
@ -43,7 +47,6 @@ export class DebugController extends SdkObject {
|
|||
private _trackHierarchyListener: InstrumentationListener | undefined;
|
||||
private _playwright: Playwright;
|
||||
_sdkLanguage: Language = 'javascript';
|
||||
_codegenId: string = 'playwright-test';
|
||||
|
||||
constructor(playwright: Playwright) {
|
||||
super({ attribution: { isInternalPlaywright: true }, instrumentation: createInstrumentation() } as any, undefined, 'DebugController');
|
||||
|
@ -51,7 +54,6 @@ export class DebugController extends SdkObject {
|
|||
}
|
||||
|
||||
initialize(codegenId: string, sdkLanguage: Language) {
|
||||
this._codegenId = codegenId;
|
||||
this._sdkLanguage = sdkLanguage;
|
||||
}
|
||||
|
||||
|
@ -86,8 +88,7 @@ export class DebugController extends SdkObject {
|
|||
await p.mainFrame().goto(progress, url);
|
||||
}
|
||||
|
||||
async setRecorderMode(progress: Progress, params: { mode: Mode, file?: string, testIdAttributeName?: string }) {
|
||||
// TODO: |file| is only used in the legacy mode.
|
||||
async setRecorderMode(progress: Progress, params: { mode: Mode, testIdAttributeName?: string }) {
|
||||
await progress.race(this._closeBrowsersWithoutPages());
|
||||
|
||||
if (params.mode === 'none') {
|
||||
|
@ -115,8 +116,6 @@ export class DebugController extends SdkObject {
|
|||
// Toggle the mode.
|
||||
for (const recorder of await progress.race(this._allRecorders())) {
|
||||
recorder.hideHighlightedSelector();
|
||||
if (params.mode !== 'inspecting')
|
||||
recorder.setOutput(this._codegenId, params.file);
|
||||
recorder.setMode(params.mode);
|
||||
}
|
||||
}
|
||||
|
@ -188,10 +187,13 @@ export class DebugController extends SdkObject {
|
|||
|
||||
class InspectingRecorderApp extends EmptyRecorderApp {
|
||||
private _debugController: DebugController;
|
||||
private _actions: actions.ActionInContext[] = [];
|
||||
private _languageGenerator: JavaScriptLanguageGenerator;
|
||||
|
||||
constructor(debugController: DebugController) {
|
||||
super();
|
||||
this._debugController = debugController;
|
||||
this._languageGenerator = new JavaScriptLanguageGenerator(/* isPlaywrightTest */true);
|
||||
}
|
||||
|
||||
override async elementPicked(elementInfo: ElementInfo): Promise<void> {
|
||||
|
@ -199,12 +201,6 @@ class InspectingRecorderApp extends EmptyRecorderApp {
|
|||
this._debugController.emit(DebugController.Events.InspectRequested, { selector: elementInfo.selector, locator, ariaSnapshot: elementInfo.ariaSnapshot });
|
||||
}
|
||||
|
||||
override async setSources(sources: Source[]): Promise<void> {
|
||||
const source = sources.find(s => s.id === this._debugController._codegenId);
|
||||
const { text, header, footer, actions } = source || { text: '' };
|
||||
this._debugController.emit(DebugController.Events.SourceChanged, { text, header, footer, actions });
|
||||
}
|
||||
|
||||
override async setPaused(paused: boolean) {
|
||||
this._debugController.emit(DebugController.Events.Paused, { paused });
|
||||
}
|
||||
|
@ -212,4 +208,26 @@ class InspectingRecorderApp extends EmptyRecorderApp {
|
|||
override async setMode(mode: Mode) {
|
||||
this._debugController.emit(DebugController.Events.SetModeRequested, { mode });
|
||||
}
|
||||
|
||||
override async actionAdded(action: actions.ActionInContext): Promise<void> {
|
||||
this._actions.push(action);
|
||||
this._actionsChanged();
|
||||
}
|
||||
|
||||
override async signalAdded(signal: actions.Signal): Promise<void> {
|
||||
const lastAction = this._actions[this._actions.length - 1];
|
||||
if (lastAction)
|
||||
lastAction.action.signals.push(signal);
|
||||
this._actionsChanged();
|
||||
}
|
||||
|
||||
private _actionsChanged() {
|
||||
const actions = collapseActions(this._actions);
|
||||
const { header, footer, text, actionTexts } = generateCode(actions, this._languageGenerator, {
|
||||
browserName: 'chromium',
|
||||
launchOptions: {},
|
||||
contextOptions: {},
|
||||
});
|
||||
this._debugController.emit(DebugController.Events.SourceChanged, { text, header, footer, actions: actionTexts });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ import { APIRequestContextDispatcher, RequestDispatcher, ResponseDispatcher, Rou
|
|||
import { BindingCallDispatcher, PageDispatcher, WorkerDispatcher } from './pageDispatcher';
|
||||
import { CRBrowserContext } from '../chromium/crBrowser';
|
||||
import { serializeError } from '../errors';
|
||||
import { Recorder } from '../recorder';
|
||||
import { TracingDispatcher } from './tracingDispatcher';
|
||||
import { WebSocketRouteDispatcher } from './webSocketRouteDispatcher';
|
||||
import { WritableStreamDispatcher } from './writableStreamDispatcher';
|
||||
|
@ -332,7 +331,7 @@ export class BrowserContextDispatcher extends Dispatcher<BrowserContext, channel
|
|||
}
|
||||
|
||||
async enableRecorder(params: channels.BrowserContextEnableRecorderParams, progress: Progress): Promise<void> {
|
||||
await Recorder.show(this._context, RecorderApp.factory(this._context), params);
|
||||
await RecorderApp.show(this._context, params);
|
||||
}
|
||||
|
||||
async pause(params: channels.BrowserContextPauseParams, progress: Progress) {
|
||||
|
|
|
@ -27,16 +27,12 @@ import { serverSideCallMetadata } from './instrumentation';
|
|||
import { RecorderSignalProcessor } from './recorder/recorderSignalProcessor';
|
||||
import * as rawRecorderSource from './../generated/pollingRecorderSource';
|
||||
import { eventsHelper, monotonicTime } from './../utils';
|
||||
import { languageSet } from './codegen/languages';
|
||||
import { Frame } from './frames';
|
||||
import { Page } from './page';
|
||||
import { ThrottledFile } from './recorder/throttledFile';
|
||||
import { generateCode } from './codegen/language';
|
||||
import { performAction } from './recorder/recorderRunner';
|
||||
import { collapseActions } from './recorder/recorderUtils';
|
||||
|
||||
|
||||
import type { Language, LanguageGenerator, LanguageGeneratorOptions } from './codegen/types';
|
||||
import type { Language } from './codegen/types';
|
||||
import type { CallMetadata, InstrumentationListener, SdkObject } from './instrumentation';
|
||||
import type { IRecorder, IRecorderApp, IRecorderAppFactory } from './recorder/recorderFrontend';
|
||||
import type { Point } from '../utils/isomorphic/types';
|
||||
|
@ -60,11 +56,10 @@ export class Recorder implements InstrumentationListener, IRecorder {
|
|||
private _overlayState: OverlayState = { offsetX: 0 };
|
||||
private _recorderApp: IRecorderApp | null = null;
|
||||
private _currentCallsMetadata = new Map<CallMetadata, SdkObject>();
|
||||
private _recorderSources: Source[] = [];
|
||||
private _userSources = new Map<string, Source>();
|
||||
private _debugger: Debugger;
|
||||
private _omitCallTracking = false;
|
||||
private _currentLanguage: Language;
|
||||
private _currentLanguage: Language = 'javascript';
|
||||
private _recorderMode: 'record' | 'perform';
|
||||
|
||||
private _signalProcessor: RecorderSignalProcessor;
|
||||
|
@ -72,23 +67,13 @@ export class Recorder implements InstrumentationListener, IRecorder {
|
|||
private _lastPopupOrdinal = 0;
|
||||
private _lastDialogOrdinal = -1;
|
||||
private _lastDownloadOrdinal = -1;
|
||||
private _throttledOutputFile: ThrottledFile | null = null;
|
||||
private _orderedLanguages: LanguageGenerator[] = [];
|
||||
private _listeners: RegisteredListener[] = [];
|
||||
private _actions: actions.ActionInContext[] = [];
|
||||
private _languageGeneratorOptions: LanguageGeneratorOptions;
|
||||
private _enabled: boolean = false;
|
||||
|
||||
static async showInspector(context: BrowserContext, params: channels.BrowserContextEnableRecorderParams, recorderAppFactory: IRecorderAppFactory) {
|
||||
if (isUnderTest())
|
||||
params.language = process.env.TEST_INSPECTOR_LANGUAGE;
|
||||
return await Recorder.show(context, recorderAppFactory, params);
|
||||
}
|
||||
|
||||
static showInspectorNoReply(context: BrowserContext, recorderAppFactory: IRecorderAppFactory) {
|
||||
Recorder.showInspector(context, {}, recorderAppFactory).catch(() => {});
|
||||
}
|
||||
|
||||
static show(context: BrowserContext, recorderAppFactory: IRecorderAppFactory, params: channels.BrowserContextEnableRecorderParams): Promise<Recorder> {
|
||||
let recorderPromise = (context as any)[recorderSymbol] as Promise<Recorder>;
|
||||
if (!recorderPromise) {
|
||||
|
@ -102,6 +87,7 @@ export class Recorder implements InstrumentationListener, IRecorder {
|
|||
const recorder = new Recorder(context, params);
|
||||
const recorderApp = await recorderAppFactory(recorder);
|
||||
await recorder._install(recorderApp);
|
||||
recorderApp.start();
|
||||
return recorder;
|
||||
}
|
||||
|
||||
|
@ -112,46 +98,28 @@ export class Recorder implements InstrumentationListener, IRecorder {
|
|||
this._recorderMode = params.recorderMode ?? 'perform';
|
||||
this.handleSIGINT = params.handleSIGINT;
|
||||
|
||||
// Make a copy of options to modify them later.
|
||||
this._languageGeneratorOptions = {
|
||||
browserName: context._browser.options.name,
|
||||
launchOptions: { headless: false, ...params.launchOptions, tracesDir: undefined },
|
||||
contextOptions: { ...params.contextOptions },
|
||||
deviceName: params.device,
|
||||
saveStorage: params.saveStorage,
|
||||
};
|
||||
|
||||
this._signalProcessor = new RecorderSignalProcessor();
|
||||
this._signalProcessor.on('action', (actionInContext: actions.ActionInContext) => {
|
||||
if (!this._enabled)
|
||||
return;
|
||||
this._actions.push(actionInContext);
|
||||
this._updateActions();
|
||||
if (this._enabled)
|
||||
this._recorderApp?.actionAdded(actionInContext);
|
||||
});
|
||||
this._signalProcessor.on('signal', (signal: Signal) => {
|
||||
if (!this._enabled)
|
||||
return;
|
||||
const lastAction = this._actions[this._actions.length - 1];
|
||||
if (lastAction)
|
||||
lastAction.action.signals.push(signal);
|
||||
this._updateActions();
|
||||
if (this._enabled)
|
||||
this._recorderApp?.signalAdded(signal);
|
||||
});
|
||||
|
||||
context.on(BrowserContext.Events.BeforeClose, () => {
|
||||
this._throttledOutputFile?.flush();
|
||||
this._recorderApp?.flushOutput().catch(() => {});
|
||||
});
|
||||
this._listeners.push(eventsHelper.addEventListener(process, 'exit', () => {
|
||||
this._throttledOutputFile?.flush();
|
||||
this._recorderApp?.flushOutput().catch(() => {});
|
||||
}));
|
||||
|
||||
const language = params.language || context._browser.sdkLanguage();
|
||||
this._innerSetOutput(language, params.outputFile);
|
||||
this._setEnabled(params.mode === 'recording');
|
||||
|
||||
this._omitCallTracking = !!params.omitCallTracking;
|
||||
this._debugger = context.debugger();
|
||||
context.instrumentation.addListener(this, context);
|
||||
this._currentLanguage = this._languageName();
|
||||
|
||||
if (isUnderTest()) {
|
||||
// Most of our tests put elements at the top left, so get out of the way.
|
||||
|
@ -181,8 +149,8 @@ export class Recorder implements InstrumentationListener, IRecorder {
|
|||
this._debugger.resume(true);
|
||||
return;
|
||||
}
|
||||
if (data.event === 'fileChanged') {
|
||||
this._currentLanguage = this._languageName(data.params.file);
|
||||
if (data.event === 'languageChanged') {
|
||||
this._currentLanguage = data.params.language;
|
||||
this._refreshOverlay();
|
||||
return;
|
||||
}
|
||||
|
@ -203,7 +171,7 @@ export class Recorder implements InstrumentationListener, IRecorder {
|
|||
await Promise.all([
|
||||
recorderApp.setMode(this._mode),
|
||||
recorderApp.setPaused(this._debugger.isPaused()),
|
||||
this._pushAllSources()
|
||||
this._pushUserSources()
|
||||
]);
|
||||
|
||||
this._context.once(BrowserContext.Events.Close, () => {
|
||||
|
@ -361,21 +329,6 @@ export class Recorder implements InstrumentationListener, IRecorder {
|
|||
}
|
||||
}
|
||||
|
||||
setOutput(codegenId: string, outputFile: string | undefined) {
|
||||
this._innerSetOutput(codegenId, outputFile);
|
||||
this._resetActions();
|
||||
}
|
||||
|
||||
private _innerSetOutput(codegenId: string, outputFile: string | undefined) {
|
||||
const languages = languageSet();
|
||||
const primaryLanguage = [...languages].find(l => l.id === codegenId);
|
||||
if (!primaryLanguage)
|
||||
throw new Error(`\n===============================\nUnsupported language: '${codegenId}'\n===============================\n`);
|
||||
languages.delete(primaryLanguage);
|
||||
this._orderedLanguages = [primaryLanguage, ...languages];
|
||||
this._throttledOutputFile = outputFile ? new ThrottledFile(outputFile) : null;
|
||||
}
|
||||
|
||||
private _refreshOverlay() {
|
||||
for (const page of this._context.pages()) {
|
||||
for (const frame of page.frames())
|
||||
|
@ -406,37 +359,33 @@ export class Recorder implements InstrumentationListener, IRecorder {
|
|||
|
||||
private _updateUserSources() {
|
||||
// Remove old decorations.
|
||||
const timestamp = monotonicTime();
|
||||
for (const source of this._userSources.values()) {
|
||||
source.highlight = [];
|
||||
source.revealLine = undefined;
|
||||
}
|
||||
|
||||
// Apply new decorations.
|
||||
let fileToSelect = undefined;
|
||||
for (const metadata of this._currentCallsMetadata.keys()) {
|
||||
if (!metadata.location)
|
||||
continue;
|
||||
const { file, line } = metadata.location;
|
||||
let source = this._userSources.get(file);
|
||||
if (!source) {
|
||||
source = { isRecorded: false, label: file, id: file, text: this._readSource(file), highlight: [], language: languageForFile(file) };
|
||||
source = { isPrimary: false, isRecorded: false, label: file, id: file, text: this._readSource(file), highlight: [], language: languageForFile(file), timestamp };
|
||||
this._userSources.set(file, source);
|
||||
}
|
||||
if (line) {
|
||||
const paused = this._debugger.isPaused(metadata);
|
||||
source.highlight.push({ line, type: metadata.error ? 'error' : (paused ? 'paused' : 'running') });
|
||||
source.revealLine = line;
|
||||
fileToSelect = source.id;
|
||||
}
|
||||
}
|
||||
this._pushAllSources();
|
||||
if (fileToSelect)
|
||||
this._recorderApp?.setRunningFile(fileToSelect);
|
||||
this._pushUserSources();
|
||||
}
|
||||
|
||||
private _pushAllSources() {
|
||||
const primaryPage: Page | undefined = this._context.pages()[0];
|
||||
this._recorderApp?.setSources([...this._recorderSources, ...this._userSources.values()], primaryPage?.mainFrame().url());
|
||||
private _pushUserSources() {
|
||||
this._recorderApp?.userSourcesChanged([...this._userSources.values()]);
|
||||
}
|
||||
|
||||
async onBeforeInputAction(sdkObject: SdkObject, metadata: CallMetadata) {
|
||||
|
@ -475,48 +424,6 @@ export class Recorder implements InstrumentationListener, IRecorder {
|
|||
}
|
||||
}
|
||||
|
||||
private _resetActions() {
|
||||
this._actions = [];
|
||||
this._updateActions();
|
||||
}
|
||||
|
||||
private _updateActions() {
|
||||
const actions = collapseActions(this._actions);
|
||||
const recorderSources = [];
|
||||
for (const languageGenerator of this._orderedLanguages) {
|
||||
const { header, footer, actionTexts, text } = generateCode(actions, languageGenerator, this._languageGeneratorOptions);
|
||||
const source: Source = {
|
||||
isRecorded: true,
|
||||
label: languageGenerator.name,
|
||||
group: languageGenerator.groupName,
|
||||
id: languageGenerator.id,
|
||||
text,
|
||||
header,
|
||||
footer,
|
||||
actions: actionTexts,
|
||||
language: languageGenerator.highlighter,
|
||||
highlight: []
|
||||
};
|
||||
source.revealLine = text.split('\n').length - 1;
|
||||
recorderSources.push(source);
|
||||
if (languageGenerator === this._orderedLanguages[0])
|
||||
this._throttledOutputFile?.setContent(source.text);
|
||||
}
|
||||
|
||||
this._recorderSources = recorderSources;
|
||||
this._recorderApp?.setActions(actions, recorderSources);
|
||||
this._recorderApp?.setRunningFile(undefined);
|
||||
this._pushAllSources();
|
||||
}
|
||||
|
||||
private _languageName(id?: string): Language {
|
||||
for (const lang of this._orderedLanguages) {
|
||||
if (!id || lang.id === id)
|
||||
return lang.highlighter;
|
||||
}
|
||||
return 'javascript';
|
||||
}
|
||||
|
||||
private _setEnabled(enabled: boolean) {
|
||||
this._enabled = enabled;
|
||||
}
|
||||
|
@ -534,10 +441,13 @@ export class Recorder implements InstrumentationListener, IRecorder {
|
|||
startTime: monotonicTime()
|
||||
});
|
||||
this._pageAliases.delete(page);
|
||||
this._filePrimaryURLChanged();
|
||||
});
|
||||
frame.on(Frame.Events.InternalNavigation, event => {
|
||||
if (event.isPublic)
|
||||
if (event.isPublic) {
|
||||
this._onFrameNavigated(frame, page);
|
||||
this._filePrimaryURLChanged();
|
||||
}
|
||||
});
|
||||
page.on(Page.Events.Download, () => this._onDownload(page));
|
||||
const suffix = this._pageAliases.size ? String(++this._lastPopupOrdinal) : '';
|
||||
|
@ -557,10 +467,15 @@ export class Recorder implements InstrumentationListener, IRecorder {
|
|||
startTime: monotonicTime()
|
||||
});
|
||||
}
|
||||
this._filePrimaryURLChanged();
|
||||
}
|
||||
|
||||
private _filePrimaryURLChanged() {
|
||||
const page = this._context.pages()[0];
|
||||
this._recorderApp?.pageNavigated(page?.mainFrame().url());
|
||||
}
|
||||
|
||||
private _clearScript(): void {
|
||||
this._resetActions();
|
||||
if (this._params.mode === 'recording') {
|
||||
for (const page of this._context.pages())
|
||||
this._onFrameNavigated(page.mainFrame(), page);
|
||||
|
|
|
@ -24,40 +24,63 @@ import { serverSideCallMetadata } from '../instrumentation';
|
|||
import { syncLocalStorageWithSettings } from '../launchApp';
|
||||
import { launchApp } from '../launchApp';
|
||||
import { ProgressController } from '../progress';
|
||||
import { ThrottledFile } from './throttledFile';
|
||||
import { languageSet } from '../codegen/languages';
|
||||
import { collapseActions } from './recorderUtils';
|
||||
import { generateCode } from '../codegen/language';
|
||||
import { Recorder } from '../recorder';
|
||||
import { monotonicTime } from '../../utils/isomorphic/time';
|
||||
|
||||
import type { BrowserContext } from '../browserContext';
|
||||
import type { Page } from '../page';
|
||||
import type { IRecorder, IRecorderApp, IRecorderAppFactory } from './recorderFrontend';
|
||||
import type { IRecorder, IRecorderApp, IRecorderAppFactory, RecorderAppParams } from './recorderFrontend';
|
||||
import type * as actions from '@recorder/actions';
|
||||
import type { CallLog, ElementInfo, Mode, Source } from '@recorder/recorderTypes';
|
||||
import type { LanguageGeneratorOptions } from '../codegen/types';
|
||||
import type * as channels from '@protocol/channels';
|
||||
|
||||
export class EmptyRecorderApp extends EventEmitter implements IRecorderApp {
|
||||
wsEndpointForTest: undefined;
|
||||
async close(): Promise<void> {}
|
||||
async setPaused(paused: boolean): Promise<void> {}
|
||||
async setMode(mode: Mode): Promise<void> {}
|
||||
async setRunningFile(file: string | undefined): Promise<void> {}
|
||||
async elementPicked(elementInfo: ElementInfo, userGesture?: boolean): Promise<void> {}
|
||||
async updateCallLogs(callLogs: CallLog[]): Promise<void> {}
|
||||
async setSources(sources: Source[], primaryPageURL: string | undefined): Promise<void> {}
|
||||
async setActions(actions: actions.ActionInContext[], sources: Source[]): Promise<void> {}
|
||||
async userSourcesChanged(sources: Source[]): Promise<void> {}
|
||||
async start() {}
|
||||
async actionAdded(action: actions.ActionInContext): Promise<void> {}
|
||||
async signalAdded(signal: actions.Signal): Promise<void> {}
|
||||
async pageNavigated(url: string): Promise<void> {}
|
||||
async flushOutput(): Promise<void> {}
|
||||
}
|
||||
|
||||
export class RecorderApp extends EventEmitter implements IRecorderApp {
|
||||
private _page: Page;
|
||||
readonly wsEndpointForTest: string | undefined;
|
||||
private _recorder: IRecorder;
|
||||
private _languageGeneratorOptions: LanguageGeneratorOptions;
|
||||
private _throttledOutputFile: ThrottledFile | null = null;
|
||||
private _actions: actions.ActionInContext[] = [];
|
||||
private _userSources: Source[] = [];
|
||||
private _recorderSources: Source[] = [];
|
||||
private _primaryLanguage: string;
|
||||
|
||||
constructor(recorder: IRecorder, page: Page, wsEndpoint: string | undefined) {
|
||||
constructor(params: RecorderAppParams, page: Page, wsEndpointForTest: string | undefined) {
|
||||
super();
|
||||
this.setMaxListeners(0);
|
||||
this._recorder = recorder;
|
||||
this._page = page;
|
||||
this.wsEndpointForTest = wsEndpoint;
|
||||
}
|
||||
this.wsEndpointForTest = wsEndpointForTest;
|
||||
|
||||
async close() {
|
||||
await this._page.browserContext.close({ reason: 'Recorder window closed' });
|
||||
// Make a copy of options to modify them later.
|
||||
this._languageGeneratorOptions = {
|
||||
browserName: params.browserName,
|
||||
launchOptions: { headless: false, ...params.launchOptions, tracesDir: undefined },
|
||||
contextOptions: { ...params.contextOptions },
|
||||
deviceName: params.device,
|
||||
saveStorage: params.saveStorage,
|
||||
};
|
||||
|
||||
this._throttledOutputFile = params.outputFile ? new ThrottledFile(params.outputFile) : null;
|
||||
this._primaryLanguage = process.env.TEST_INSPECTOR_LANGUAGE || params.language || params.sdkLanguage;
|
||||
}
|
||||
|
||||
private async _init() {
|
||||
|
@ -85,7 +108,7 @@ export class RecorderApp extends EventEmitter implements IRecorderApp {
|
|||
});
|
||||
});
|
||||
|
||||
await this._page.exposeBinding(progress, 'dispatch', false, (_, data: any) => this.emit('event', data));
|
||||
await this._page.exposeBinding(progress, 'dispatch', false, (_, data: any) => this._handleUIEvent(data));
|
||||
|
||||
this._page.once('close', () => {
|
||||
this.emit('close');
|
||||
|
@ -96,15 +119,78 @@ export class RecorderApp extends EventEmitter implements IRecorderApp {
|
|||
});
|
||||
}
|
||||
|
||||
static factory(context: BrowserContext): IRecorderAppFactory {
|
||||
start() {
|
||||
this._updateActions(true);
|
||||
}
|
||||
|
||||
async actionAdded(action: actions.ActionInContext): Promise<void> {
|
||||
this._actions.push(action);
|
||||
this._updateActions();
|
||||
}
|
||||
|
||||
async signalAdded(signal: actions.Signal): Promise<void> {
|
||||
const lastAction = this._actions[this._actions.length - 1];
|
||||
if (lastAction)
|
||||
lastAction.action.signals.push(signal);
|
||||
this._updateActions();
|
||||
}
|
||||
|
||||
async pageNavigated(url: string): Promise<void> {
|
||||
await this._page.mainFrame().evaluateExpression((({ url }: { url: string }) => {
|
||||
window.playwrightSetPageURL(url);
|
||||
}).toString(), { isFunction: true }, { url }).catch(() => {});
|
||||
}
|
||||
|
||||
private _selectedFileChanged(fileId: string) {
|
||||
const source = [...this._recorderSources, ...this._userSources].find(s => s.id === fileId);
|
||||
if (source)
|
||||
this.emit('event', { event: 'languageChanged', params: { language: source.language } });
|
||||
}
|
||||
|
||||
async close() {
|
||||
await this._page.browserContext.close({ reason: 'Recorder window closed' });
|
||||
}
|
||||
|
||||
private _handleUIEvent(data: any) {
|
||||
if (data.event === 'clear') {
|
||||
this._actions = [];
|
||||
this._updateActions();
|
||||
this.emit('clear');
|
||||
return;
|
||||
}
|
||||
if (data.event === 'fileChanged') {
|
||||
this._selectedFileChanged(data.params.fileId);
|
||||
return;
|
||||
}
|
||||
|
||||
// Pass through events.
|
||||
this.emit('event', data);
|
||||
}
|
||||
|
||||
static async show(context: BrowserContext, params: channels.BrowserContextEnableRecorderParams) {
|
||||
const factory = RecorderApp._factory(context, params);
|
||||
await Recorder.show(context, factory, params);
|
||||
}
|
||||
|
||||
static showInspectorNoReply(context: BrowserContext) {
|
||||
Recorder.showInspector(context, {}, RecorderApp._factory(context, {})).catch(() => {});
|
||||
}
|
||||
|
||||
private static _factory(context: BrowserContext, params: channels.BrowserContextEnableRecorderParams): IRecorderAppFactory {
|
||||
const appParams = {
|
||||
browserName: context._browser.options.name,
|
||||
sdkLanguage: context._browser.sdkLanguage(),
|
||||
wsEndpointForTest: context._browser.options.wsEndpoint,
|
||||
...params,
|
||||
};
|
||||
return async recorder => {
|
||||
if (process.env.PW_CODEGEN_NO_INSPECTOR)
|
||||
return new EmptyRecorderApp();
|
||||
return await RecorderApp._open(recorder, context);
|
||||
return await RecorderApp._open(appParams, recorder, context);
|
||||
};
|
||||
}
|
||||
|
||||
private static async _open(recorder: IRecorder, inspectedContext: BrowserContext): Promise<IRecorderApp> {
|
||||
private static async _open(params: RecorderAppParams, recorder: IRecorder, inspectedContext: BrowserContext): Promise<IRecorderApp> {
|
||||
const sdkLanguage = inspectedContext._browser.sdkLanguage();
|
||||
const headed = !!inspectedContext._browser.options.headful;
|
||||
const recorderPlaywright = (require('../playwright').createPlaywright as typeof import('../playwright').createPlaywright)({ sdkLanguage: 'javascript', isInternalPlaywright: true });
|
||||
|
@ -116,7 +202,7 @@ export class RecorderApp extends EventEmitter implements IRecorderApp {
|
|||
noDefaultViewport: true,
|
||||
headless: !!process.env.PWTEST_CLI_HEADLESS || (isUnderTest() && !headed),
|
||||
cdpPort: isUnderTest() ? 0 : undefined,
|
||||
handleSIGINT: recorder.handleSIGINT,
|
||||
handleSIGINT: params.handleSIGINT,
|
||||
executablePath: inspectedContext._browser.options.isChromium ? inspectedContext._browser.options.customExecutablePath : undefined,
|
||||
// Use the same channel as the inspected context to guarantee that the browser is installed.
|
||||
channel: inspectedContext._browser.options.isChromium ? inspectedContext._browser.options.channel : undefined,
|
||||
|
@ -127,7 +213,7 @@ export class RecorderApp extends EventEmitter implements IRecorderApp {
|
|||
await context._browser._defaultContext!._loadDefaultContextAsIs(progress);
|
||||
});
|
||||
|
||||
const result = new RecorderApp(recorder, page, context._browser.options.wsEndpoint);
|
||||
const result = new RecorderApp(params, page, context._browser.options.wsEndpoint);
|
||||
await result._init();
|
||||
return result;
|
||||
}
|
||||
|
@ -138,33 +224,33 @@ export class RecorderApp extends EventEmitter implements IRecorderApp {
|
|||
}).toString(), { isFunction: true }, mode).catch(() => {});
|
||||
}
|
||||
|
||||
async setRunningFile(file: string | undefined): Promise<void> {
|
||||
await this._page.mainFrame().evaluateExpression(((file: string) => {
|
||||
window.playwrightSetRunningFile(file);
|
||||
}).toString(), { isFunction: true }, file).catch(() => {});
|
||||
}
|
||||
|
||||
async setPaused(paused: boolean): Promise<void> {
|
||||
await this._page.mainFrame().evaluateExpression(((paused: boolean) => {
|
||||
window.playwrightSetPaused(paused);
|
||||
}).toString(), { isFunction: true }, paused).catch(() => {});
|
||||
}
|
||||
|
||||
async setSources(sources: Source[], primaryPageURL: string | undefined): Promise<void> {
|
||||
await this._page.mainFrame().evaluateExpression((({ sources, primaryPageURL }: { sources: Source[], primaryPageURL: string | undefined }) => {
|
||||
window.playwrightSetSources(sources, primaryPageURL);
|
||||
}).toString(), { isFunction: true }, { sources, primaryPageURL }).catch(() => {});
|
||||
async userSourcesChanged(sources: Source[]): Promise<void> {
|
||||
if (!sources.length && !this._userSources.length)
|
||||
return;
|
||||
this._userSources = sources;
|
||||
this._pushAllSources();
|
||||
}
|
||||
|
||||
private async _pushAllSources() {
|
||||
const sources = [...this._userSources, ...this._recorderSources];
|
||||
this._page.mainFrame().evaluateExpression((({ sources }: { sources: Source[] }) => {
|
||||
window.playwrightSetSources(sources);
|
||||
}).toString(), { isFunction: true }, { sources }).catch(() => {});
|
||||
|
||||
// Testing harness for runCLI mode.
|
||||
if (process.env.PWTEST_CLI_IS_UNDER_TEST && sources.length) {
|
||||
if ((process as any)._didSetSourcesForTest(sources[0].text))
|
||||
const primarySource = sources.find(s => s.isPrimary);
|
||||
if ((process as any)._didSetSourcesForTest(primarySource?.text ?? ''))
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
|
||||
async setActions(actions: actions.ActionInContext[], sources: Source[]): Promise<void> {
|
||||
}
|
||||
|
||||
async elementPicked(elementInfo: ElementInfo, userGesture?: boolean): Promise<void> {
|
||||
if (userGesture)
|
||||
this._page.bringToFront();
|
||||
|
@ -178,4 +264,39 @@ export class RecorderApp extends EventEmitter implements IRecorderApp {
|
|||
window.playwrightUpdateLogs(callLogs);
|
||||
}).toString(), { isFunction: true }, callLogs).catch(() => {});
|
||||
}
|
||||
|
||||
async flushOutput(): Promise<void> {
|
||||
this._throttledOutputFile?.flush();
|
||||
}
|
||||
|
||||
private _updateActions(initial: boolean = false) {
|
||||
const timestamp = initial ? 0 : monotonicTime();
|
||||
const recorderSources = [];
|
||||
const actions = collapseActions(this._actions);
|
||||
|
||||
for (const languageGenerator of languageSet()) {
|
||||
const { header, footer, actionTexts, text } = generateCode(actions, languageGenerator, this._languageGeneratorOptions);
|
||||
const source: Source = {
|
||||
isPrimary: languageGenerator.id === this._primaryLanguage,
|
||||
timestamp,
|
||||
isRecorded: true,
|
||||
label: languageGenerator.name,
|
||||
group: languageGenerator.groupName,
|
||||
id: languageGenerator.id,
|
||||
text,
|
||||
header,
|
||||
footer,
|
||||
actions: actionTexts,
|
||||
language: languageGenerator.highlighter,
|
||||
highlight: []
|
||||
};
|
||||
source.revealLine = text.split('\n').length - 1;
|
||||
recorderSources.push(source);
|
||||
if (languageGenerator.id === this._primaryLanguage)
|
||||
this._throttledOutputFile?.setContent(source.text);
|
||||
}
|
||||
|
||||
this._recorderSources = recorderSources;
|
||||
this._pushAllSources();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,11 +17,12 @@
|
|||
import type * as actions from '@recorder/actions';
|
||||
import type { CallLog, ElementInfo, Mode, Source } from '@recorder/recorderTypes';
|
||||
import type { EventEmitter } from 'events';
|
||||
import type * as channels from '@protocol/channels';
|
||||
import type { Language } from '../codegen/types';
|
||||
|
||||
export interface IRecorder {
|
||||
setMode(mode: Mode): void;
|
||||
mode(): Mode;
|
||||
readonly handleSIGINT: boolean | undefined;
|
||||
}
|
||||
|
||||
export interface IRecorderApp extends EventEmitter {
|
||||
|
@ -29,11 +30,19 @@ export interface IRecorderApp extends EventEmitter {
|
|||
close(): Promise<void>;
|
||||
setPaused(paused: boolean): Promise<void>;
|
||||
setMode(mode: Mode): Promise<void>;
|
||||
setRunningFile(file: string | undefined): Promise<void>;
|
||||
elementPicked(elementInfo: ElementInfo, userGesture?: boolean): Promise<void>;
|
||||
updateCallLogs(callLogs: CallLog[]): Promise<void>;
|
||||
setSources(sources: Source[], primaryPageURL: string | undefined): Promise<void>;
|
||||
setActions(actions: actions.ActionInContext[], sources: Source[]): Promise<void>;
|
||||
userSourcesChanged(sources: Source[]): Promise<void>;
|
||||
start(): void;
|
||||
actionAdded(action: actions.ActionInContext): Promise<void>;
|
||||
signalAdded(signal: actions.Signal): Promise<void>;
|
||||
pageNavigated(url: string): Promise<void>;
|
||||
flushOutput(): Promise<void>;
|
||||
}
|
||||
|
||||
export type RecorderAppParams = channels.BrowserContextEnableRecorderParams & {
|
||||
browserName: string;
|
||||
sdkLanguage: Language;
|
||||
};
|
||||
|
||||
export type IRecorderAppFactory = (recorder: IRecorder) => Promise<IRecorderApp>;
|
||||
|
|
|
@ -27,11 +27,13 @@ export const Main: React.FC = ({}) => {
|
|||
|
||||
React.useLayoutEffect(() => {
|
||||
window.playwrightSetMode = setMode;
|
||||
window.playwrightSetSources = (sources, primaryPageURL) => {
|
||||
window.playwrightSetSources = sources => {
|
||||
setSources(sources);
|
||||
window.playwrightSourcesEchoForTest = sources;
|
||||
document.title = primaryPageURL
|
||||
? `Playwright Inspector - ${primaryPageURL}`
|
||||
};
|
||||
window.playwrightSetPageURL = url => {
|
||||
document.title = url
|
||||
? `Playwright Inspector - ${url}`
|
||||
: `Playwright Inspector`;
|
||||
};
|
||||
window.playwrightSetPaused = setPaused;
|
||||
|
|
|
@ -45,21 +45,30 @@ export const Recorder: React.FC<RecorderProps> = ({
|
|||
mode,
|
||||
}) => {
|
||||
const [selectedFileId, setSelectedFileId] = React.useState<string | undefined>();
|
||||
const [runningFileId, setRunningFileId] = React.useState<string | undefined>();
|
||||
const [selectedTab, setSelectedTab] = useSetting<string>('recorderPropertiesTab', 'log');
|
||||
const [ariaSnapshot, setAriaSnapshot] = React.useState<string | undefined>();
|
||||
const [ariaSnapshotErrors, setAriaSnapshotErrors] = React.useState<SourceHighlight[]>();
|
||||
|
||||
const fileId = selectedFileId || runningFileId || sources[0]?.id;
|
||||
React.useEffect(() => {
|
||||
if (!sources.length)
|
||||
return;
|
||||
const selectedSource = sources.find(s => s.id === selectedFileId);
|
||||
const newestSource = sources.sort((a, b) => b.timestamp - a.timestamp)[0];
|
||||
if (!selectedSource || newestSource.isRecorded !== selectedSource.isRecorded) {
|
||||
// Debugger kicked in, or recording resumed. Switch selection to the newest source.
|
||||
setSelectedFileId(newestSource.id);
|
||||
}
|
||||
}, [sources, selectedFileId]);
|
||||
|
||||
const source = React.useMemo(() => {
|
||||
if (fileId) {
|
||||
const source = sources.find(s => s.id === fileId);
|
||||
const source = sources.find(s => s.id === selectedFileId);
|
||||
if (source)
|
||||
return source;
|
||||
}
|
||||
const primarySource = sources.find(s => s.isPrimary);
|
||||
if (primarySource)
|
||||
return primarySource;
|
||||
return emptySource();
|
||||
}, [sources, fileId]);
|
||||
}, [sources, selectedFileId]);
|
||||
|
||||
const [locator, setLocator] = React.useState('');
|
||||
window.playwrightElementPicked = (elementInfo: ElementInfo, userGesture?: boolean) => {
|
||||
|
@ -77,8 +86,6 @@ export const Recorder: React.FC<RecorderProps> = ({
|
|||
}
|
||||
};
|
||||
|
||||
window.playwrightSetRunningFile = setRunningFileId;
|
||||
|
||||
const messagesEndRef = React.useRef<HTMLDivElement>(null);
|
||||
React.useLayoutEffect(() => {
|
||||
messagesEndRef.current?.scrollIntoView({ block: 'center', inline: 'nearest' });
|
||||
|
@ -179,9 +186,9 @@ export const Recorder: React.FC<RecorderProps> = ({
|
|||
}}></ToolbarButton>
|
||||
<div style={{ flex: 'auto' }}></div>
|
||||
<div>Target:</div>
|
||||
<SourceChooser fileId={fileId} sources={sources} setFileId={fileId => {
|
||||
<SourceChooser fileId={source.id} sources={sources} setFileId={fileId => {
|
||||
setSelectedFileId(fileId);
|
||||
window.dispatch({ event: 'fileChanged', params: { file: fileId } });
|
||||
window.dispatch({ event: 'fileChanged', params: { fileId } });
|
||||
}} />
|
||||
<ToolbarButton icon='clear-all' title='Clear' disabled={!source || !source.text} onClick={() => {
|
||||
window.dispatch({ event: 'clear' });
|
||||
|
|
|
@ -43,7 +43,7 @@ export type EventData = {
|
|||
| 'pause'
|
||||
| 'setMode'
|
||||
| 'highlightRequested'
|
||||
| 'fileChanged';
|
||||
| 'languageChanged';
|
||||
params: any;
|
||||
};
|
||||
|
||||
|
@ -84,12 +84,14 @@ export type SourceHighlight = {
|
|||
};
|
||||
|
||||
export type Source = {
|
||||
isPrimary: boolean;
|
||||
isRecorded: boolean;
|
||||
id: string;
|
||||
label: string;
|
||||
text: string;
|
||||
language: Language;
|
||||
highlight: SourceHighlight[];
|
||||
timestamp: number;
|
||||
revealLine?: number;
|
||||
// used to group the language generators
|
||||
group?: string;
|
||||
|
@ -102,10 +104,10 @@ declare global {
|
|||
interface Window {
|
||||
playwrightSetMode: (mode: Mode) => void;
|
||||
playwrightSetPaused: (paused: boolean) => void;
|
||||
playwrightSetSources: (sources: Source[], primaryPageURL: string | undefined) => void;
|
||||
playwrightSetSources: (sources: Source[]) => void;
|
||||
playwrightSetPageURL: (url: string | undefined) => void;
|
||||
playwrightSetOverlayVisible: (visible: boolean) => void;
|
||||
playwrightUpdateLogs: (callLogs: CallLog[]) => void;
|
||||
playwrightSetRunningFile: (file: string | undefined) => void;
|
||||
playwrightElementPicked: (elementInfo: ElementInfo, userGesture?: boolean) => void;
|
||||
playwrightSourcesEchoForTest: Source[];
|
||||
dispatch(data: any): Promise<void>;
|
||||
|
|
|
@ -53,6 +53,8 @@ function renderSourceOptions(sources: Source[]): React.ReactNode {
|
|||
export function emptySource(): Source {
|
||||
return {
|
||||
id: 'default',
|
||||
timestamp: 0,
|
||||
isPrimary: false,
|
||||
isRecorded: false,
|
||||
text: '',
|
||||
language: 'javascript',
|
||||
|
|
|
@ -462,6 +462,9 @@ await page1.GotoAsync("about:blank?foo");`);
|
|||
const harFileName = testInfo.outputPath('har.har');
|
||||
const cli = runCLI([`--save-storage=${storageFileName}`, `--save-har=${harFileName}`]);
|
||||
await cli.waitFor(`import { test, expect } from '@playwright/test'`);
|
||||
// Since our interrupt is non-graceful, we need to wait for the process to settle.
|
||||
// This test should be fixed.
|
||||
await new Promise(resolve => setTimeout(resolve, 2000));
|
||||
await cli.process.kill('SIGINT');
|
||||
const { exitCode, signal } = await cli.process.exited;
|
||||
if (exitCode !== null) {
|
||||
|
|
|
@ -447,6 +447,7 @@ it.describe('pause', () => {
|
|||
})();
|
||||
const recorderPage = await recorderPageGetter();
|
||||
|
||||
await recorderPage.getByRole('combobox', { name: 'Source chooser' }).selectOption('csharp');
|
||||
const box1Promise = waitForTestLog<BoundingBox>(page, 'Highlight box for test: ');
|
||||
await recorderPage.getByText('Locator', { exact: true }).click();
|
||||
await recorderPage.locator('.tabbed-pane .CodeMirror').click();
|
||||
|
@ -541,7 +542,7 @@ it.describe('pause', () => {
|
|||
await recorder.hoverOverElement('body', { omitTooltip: true });
|
||||
await recorder.trustedClick();
|
||||
|
||||
await expect(recorderPage.getByRole('combobox', { name: 'Source chooser' })).toHaveValue('javascript');
|
||||
await expect(recorderPage.getByRole('combobox', { name: 'Source chooser' })).toHaveValue('playwright-test');
|
||||
await expect(recorderPage.locator('.cm-wrapper')).toContainText(`await page.locator('body').click();`);
|
||||
await recorderPage.getByRole('button', { name: 'Resume' }).click();
|
||||
await scriptPromise;
|
||||
|
|
|
@ -70,15 +70,11 @@ test('should update primary page URL when original primary closes', async ({
|
|||
);
|
||||
|
||||
await recorder.page.close();
|
||||
// URL will not update without performing some action
|
||||
await page3.getByRole('checkbox').click();
|
||||
await expect(recorder.recorderPage).toHaveTitle(
|
||||
`Playwright Inspector - ${server.PREFIX}/dom.html`,
|
||||
);
|
||||
|
||||
await page3.close();
|
||||
// URL will not update without performing some action
|
||||
await page4.locator('div').first().click();
|
||||
await expect(recorder.recorderPage).toHaveTitle(
|
||||
`Playwright Inspector - ${server.PREFIX}/grid.html`,
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue