Merge branch 'main' into aria-snapshots
4
.github/workflows/tests_bidi.yml
vendored
|
|
@ -7,7 +7,8 @@ on:
|
||||||
- main
|
- main
|
||||||
paths:
|
paths:
|
||||||
- .github/workflows/tests_bidi.yml
|
- .github/workflows/tests_bidi.yml
|
||||||
- packages/playwright-core/src/server/bidi/*
|
- packages/playwright-core/src/server/bidi/**
|
||||||
|
- tests/bidi/**
|
||||||
schedule:
|
schedule:
|
||||||
# Run every day at midnight
|
# Run every day at midnight
|
||||||
- cron: '0 0 * * *'
|
- cron: '0 0 * * *'
|
||||||
|
|
@ -18,7 +19,6 @@ env:
|
||||||
jobs:
|
jobs:
|
||||||
test_bidi:
|
test_bidi:
|
||||||
name: BiDi
|
name: BiDi
|
||||||
if: github.repository == 'microsoft/playwright'
|
|
||||||
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
permissions:
|
permissions:
|
||||||
|
|
|
||||||
1
.github/workflows/tests_components.yml
vendored
|
|
@ -20,7 +20,6 @@ env:
|
||||||
jobs:
|
jobs:
|
||||||
test_components:
|
test_components:
|
||||||
name: ${{ matrix.os }} - Node.js ${{ matrix.node-version }}
|
name: ${{ matrix.os }} - Node.js ${{ matrix.node-version }}
|
||||||
if: github.repository == 'microsoft/playwright'
|
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
|
|
|
||||||
5
.github/workflows/tests_others.yml
vendored
|
|
@ -21,7 +21,6 @@ env:
|
||||||
jobs:
|
jobs:
|
||||||
test_stress:
|
test_stress:
|
||||||
name: Stress - ${{ matrix.os }}
|
name: Stress - ${{ matrix.os }}
|
||||||
if: github.repository == 'microsoft/playwright'
|
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
|
|
@ -58,7 +57,6 @@ jobs:
|
||||||
|
|
||||||
test_webview2:
|
test_webview2:
|
||||||
name: WebView2
|
name: WebView2
|
||||||
if: github.repository == 'microsoft/playwright'
|
|
||||||
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
||||||
runs-on: windows-2022
|
runs-on: windows-2022
|
||||||
permissions:
|
permissions:
|
||||||
|
|
@ -89,7 +87,6 @@ jobs:
|
||||||
|
|
||||||
test_clock_frozen_time_linux:
|
test_clock_frozen_time_linux:
|
||||||
name: time library - ${{ matrix.clock }}
|
name: time library - ${{ matrix.clock }}
|
||||||
if: github.repository == 'microsoft/playwright'
|
|
||||||
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
||||||
permissions:
|
permissions:
|
||||||
id-token: write # This is required for OIDC login (azure/login) to succeed
|
id-token: write # This is required for OIDC login (azure/login) to succeed
|
||||||
|
|
@ -115,7 +112,6 @@ jobs:
|
||||||
|
|
||||||
test_clock_frozen_time_test_runner:
|
test_clock_frozen_time_test_runner:
|
||||||
name: time test runner - ${{ matrix.clock }}
|
name: time test runner - ${{ matrix.clock }}
|
||||||
if: github.repository == 'microsoft/playwright'
|
|
||||||
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
permissions:
|
permissions:
|
||||||
|
|
@ -140,7 +136,6 @@ jobs:
|
||||||
|
|
||||||
test_electron:
|
test_electron:
|
||||||
name: Electron - ${{ matrix.os }}
|
name: Electron - ${{ matrix.os }}
|
||||||
if: github.repository == 'microsoft/playwright'
|
|
||||||
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
|
|
||||||
6
.github/workflows/tests_primary.yml
vendored
|
|
@ -27,7 +27,6 @@ env:
|
||||||
jobs:
|
jobs:
|
||||||
test_linux:
|
test_linux:
|
||||||
name: ${{ matrix.os }} (${{ matrix.browser }} - Node.js ${{ matrix.node-version }})
|
name: ${{ matrix.os }} (${{ matrix.browser }} - Node.js ${{ matrix.node-version }})
|
||||||
if: github.repository == 'microsoft/playwright'
|
|
||||||
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
|
@ -60,7 +59,6 @@ jobs:
|
||||||
|
|
||||||
test_linux_chromium_tot:
|
test_linux_chromium_tot:
|
||||||
name: ${{ matrix.os }} (chromium tip-of-tree)
|
name: ${{ matrix.os }} (chromium tip-of-tree)
|
||||||
if: github.repository == 'microsoft/playwright'
|
|
||||||
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
|
@ -85,7 +83,6 @@ jobs:
|
||||||
|
|
||||||
test_test_runner:
|
test_test_runner:
|
||||||
name: Test Runner
|
name: Test Runner
|
||||||
if: github.repository == 'microsoft/playwright'
|
|
||||||
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
|
@ -130,7 +127,6 @@ jobs:
|
||||||
|
|
||||||
test_web_components:
|
test_web_components:
|
||||||
name: Web Components
|
name: Web Components
|
||||||
if: github.repository == 'microsoft/playwright'
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
@ -166,7 +162,6 @@ jobs:
|
||||||
|
|
||||||
test_vscode_extension:
|
test_vscode_extension:
|
||||||
name: VSCode Extension
|
name: VSCode Extension
|
||||||
if: github.repository == 'microsoft/playwright'
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
env:
|
||||||
PWTEST_BOT_NAME: "vscode-extension"
|
PWTEST_BOT_NAME: "vscode-extension"
|
||||||
|
|
@ -203,7 +198,6 @@ jobs:
|
||||||
|
|
||||||
test_package_installations:
|
test_package_installations:
|
||||||
name: "Installation Test ${{ matrix.os }}"
|
name: "Installation Test ${{ matrix.os }}"
|
||||||
if: github.repository == 'microsoft/playwright'
|
|
||||||
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
|
|
||||||
13
.github/workflows/tests_secondary.yml
vendored
|
|
@ -26,7 +26,6 @@ permissions:
|
||||||
jobs:
|
jobs:
|
||||||
test_linux:
|
test_linux:
|
||||||
name: ${{ matrix.os }} (${{ matrix.browser }})
|
name: ${{ matrix.os }} (${{ matrix.browser }})
|
||||||
if: github.repository == 'microsoft/playwright'
|
|
||||||
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
|
@ -47,7 +46,6 @@ jobs:
|
||||||
|
|
||||||
test_mac:
|
test_mac:
|
||||||
name: ${{ matrix.os }} (${{ matrix.browser }})
|
name: ${{ matrix.os }} (${{ matrix.browser }})
|
||||||
if: github.repository == 'microsoft/playwright'
|
|
||||||
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
|
@ -75,7 +73,6 @@ jobs:
|
||||||
|
|
||||||
test_win:
|
test_win:
|
||||||
name: "Windows"
|
name: "Windows"
|
||||||
if: github.repository == 'microsoft/playwright'
|
|
||||||
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
|
@ -95,7 +92,6 @@ jobs:
|
||||||
|
|
||||||
test-package-installations-other-node-versions:
|
test-package-installations-other-node-versions:
|
||||||
name: "Installation Test ${{ matrix.os }} (${{ matrix.node_version }})"
|
name: "Installation Test ${{ matrix.os }} (${{ matrix.node_version }})"
|
||||||
if: github.repository == 'microsoft/playwright'
|
|
||||||
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
|
|
@ -129,7 +125,6 @@ jobs:
|
||||||
|
|
||||||
headed_tests:
|
headed_tests:
|
||||||
name: "headed ${{ matrix.browser }} (${{ matrix.os }})"
|
name: "headed ${{ matrix.browser }} (${{ matrix.os }})"
|
||||||
if: github.repository == 'microsoft/playwright'
|
|
||||||
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
|
@ -156,7 +151,6 @@ jobs:
|
||||||
|
|
||||||
transport_linux:
|
transport_linux:
|
||||||
name: "Transport"
|
name: "Transport"
|
||||||
if: github.repository == 'microsoft/playwright'
|
|
||||||
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
|
@ -178,7 +172,6 @@ jobs:
|
||||||
|
|
||||||
tracing_linux:
|
tracing_linux:
|
||||||
name: Tracing ${{ matrix.browser }} ${{ matrix.channel }}
|
name: Tracing ${{ matrix.browser }} ${{ matrix.channel }}
|
||||||
if: github.repository == 'microsoft/playwright'
|
|
||||||
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
|
@ -206,7 +199,6 @@ jobs:
|
||||||
|
|
||||||
test_chromium_channels:
|
test_chromium_channels:
|
||||||
name: Test ${{ matrix.channel }} on ${{ matrix.runs-on }}
|
name: Test ${{ matrix.channel }} on ${{ matrix.runs-on }}
|
||||||
if: github.repository == 'microsoft/playwright'
|
|
||||||
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
||||||
runs-on: ${{ matrix.runs-on }}
|
runs-on: ${{ matrix.runs-on }}
|
||||||
strategy:
|
strategy:
|
||||||
|
|
@ -229,7 +221,6 @@ jobs:
|
||||||
|
|
||||||
chromium_tot:
|
chromium_tot:
|
||||||
name: Chromium tip-of-tree ${{ matrix.os }}${{ matrix.headed }}
|
name: Chromium tip-of-tree ${{ matrix.os }}${{ matrix.headed }}
|
||||||
if: github.repository == 'microsoft/playwright'
|
|
||||||
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
|
|
@ -252,7 +243,6 @@ jobs:
|
||||||
|
|
||||||
chromium_tot_headless_shell:
|
chromium_tot_headless_shell:
|
||||||
name: Chromium tip-of-tree headless-shell-${{ matrix.os }}
|
name: Chromium tip-of-tree headless-shell-${{ matrix.os }}
|
||||||
if: github.repository == 'microsoft/playwright'
|
|
||||||
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
|
|
@ -274,7 +264,6 @@ jobs:
|
||||||
|
|
||||||
firefox_beta:
|
firefox_beta:
|
||||||
name: Firefox Beta ${{ matrix.os }}
|
name: Firefox Beta ${{ matrix.os }}
|
||||||
if: github.repository == 'microsoft/playwright'
|
|
||||||
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
|
|
@ -296,7 +285,6 @@ jobs:
|
||||||
|
|
||||||
build-playwright-driver:
|
build-playwright-driver:
|
||||||
name: "build-playwright-driver"
|
name: "build-playwright-driver"
|
||||||
if: github.repository == 'microsoft/playwright'
|
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
@ -310,7 +298,6 @@ jobs:
|
||||||
|
|
||||||
test_channel_chromium:
|
test_channel_chromium:
|
||||||
name: Test channel=chromium
|
name: Test channel=chromium
|
||||||
if: github.repository == 'microsoft/playwright'
|
|
||||||
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
|
|
||||||
1
.github/workflows/tests_service.yml
vendored
|
|
@ -10,7 +10,6 @@ env:
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
name: "Service"
|
name: "Service"
|
||||||
if: github.repository == 'microsoft/playwright'
|
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
|
|
|
||||||
1
.github/workflows/tests_video.yml
vendored
|
|
@ -14,7 +14,6 @@ env:
|
||||||
jobs:
|
jobs:
|
||||||
video_linux:
|
video_linux:
|
||||||
name: "Video Linux"
|
name: "Video Linux"
|
||||||
if: github.repository == 'microsoft/playwright'
|
|
||||||
environment: allow-uploading-flakiness-results
|
environment: allow-uploading-flakiness-results
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
|
|
||||||
1
.github/workflows/trigger_tests.yml
vendored
|
|
@ -9,7 +9,6 @@ on:
|
||||||
jobs:
|
jobs:
|
||||||
trigger:
|
trigger:
|
||||||
name: "trigger"
|
name: "trigger"
|
||||||
if: github.repository == 'microsoft/playwright'
|
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
steps:
|
steps:
|
||||||
- run: |
|
- run: |
|
||||||
|
|
|
||||||
|
|
@ -2250,7 +2250,6 @@ Asserts that the target element matches the given [accessibility snapshot](../ar
|
||||||
```js
|
```js
|
||||||
await expect(page.locator('body')).toMatchAriaSnapshot();
|
await expect(page.locator('body')).toMatchAriaSnapshot();
|
||||||
await expect(page.locator('body')).toMatchAriaSnapshot({ name: 'snapshot' });
|
await expect(page.locator('body')).toMatchAriaSnapshot({ name: 'snapshot' });
|
||||||
await expect(page.locator('body')).toMatchAriaSnapshot({ path: '/path/to/snapshot.yml' });
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```python async
|
```python async
|
||||||
|
|
|
||||||
|
|
@ -15,13 +15,13 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "firefox",
|
"name": "firefox",
|
||||||
"revision": "1471",
|
"revision": "1472",
|
||||||
"installByDefault": true,
|
"installByDefault": true,
|
||||||
"browserVersion": "134.0"
|
"browserVersion": "134.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "firefox-beta",
|
"name": "firefox-beta",
|
||||||
"revision": "1467",
|
"revision": "1468",
|
||||||
"installByDefault": false,
|
"installByDefault": false,
|
||||||
"browserVersion": "133.0b9"
|
"browserVersion": "133.0b9"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -139,6 +139,9 @@ function defaultProfilePreferences(
|
||||||
'dom.min_background_timeout_value_without_budget_throttling': 0,
|
'dom.min_background_timeout_value_without_budget_throttling': 0,
|
||||||
'dom.timeout.enable_budget_timer_throttling': false,
|
'dom.timeout.enable_budget_timer_throttling': false,
|
||||||
|
|
||||||
|
// Disable HTTPS-First upgrades
|
||||||
|
'dom.security.https_first': false,
|
||||||
|
|
||||||
// Only load extensions from the application and user profile
|
// Only load extensions from the application and user profile
|
||||||
// AddonManager.SCOPE_PROFILE + AddonManager.SCOPE_APPLICATION
|
// AddonManager.SCOPE_PROFILE + AddonManager.SCOPE_APPLICATION
|
||||||
'extensions.autoDisableScopes': 0,
|
'extensions.autoDisableScopes': 0,
|
||||||
|
|
|
||||||
|
|
@ -301,6 +301,11 @@ export module Protocol {
|
||||||
forcedColors: ("active"|"none")|null;
|
forcedColors: ("active"|"none")|null;
|
||||||
};
|
};
|
||||||
export type setForcedColorsReturnValue = void;
|
export type setForcedColorsReturnValue = void;
|
||||||
|
export type setContrastParameters = {
|
||||||
|
browserContextId?: string;
|
||||||
|
contrast: ("less"|"more"|"custom"|"no-preference")|null;
|
||||||
|
};
|
||||||
|
export type setContrastReturnValue = void;
|
||||||
export type setVideoRecordingOptionsParameters = {
|
export type setVideoRecordingOptionsParameters = {
|
||||||
browserContextId?: string;
|
browserContextId?: string;
|
||||||
options?: {
|
options?: {
|
||||||
|
|
@ -530,6 +535,7 @@ export module Protocol {
|
||||||
colorScheme?: ("dark"|"light"|"no-preference");
|
colorScheme?: ("dark"|"light"|"no-preference");
|
||||||
reducedMotion?: ("reduce"|"no-preference");
|
reducedMotion?: ("reduce"|"no-preference");
|
||||||
forcedColors?: ("active"|"none");
|
forcedColors?: ("active"|"none");
|
||||||
|
contrast?: ("less"|"more"|"custom"|"no-preference");
|
||||||
};
|
};
|
||||||
export type setEmulatedMediaReturnValue = void;
|
export type setEmulatedMediaReturnValue = void;
|
||||||
export type setCacheDisabledParameters = {
|
export type setCacheDisabledParameters = {
|
||||||
|
|
@ -1131,6 +1137,7 @@ export module Protocol {
|
||||||
"Browser.setColorScheme": Browser.setColorSchemeParameters;
|
"Browser.setColorScheme": Browser.setColorSchemeParameters;
|
||||||
"Browser.setReducedMotion": Browser.setReducedMotionParameters;
|
"Browser.setReducedMotion": Browser.setReducedMotionParameters;
|
||||||
"Browser.setForcedColors": Browser.setForcedColorsParameters;
|
"Browser.setForcedColors": Browser.setForcedColorsParameters;
|
||||||
|
"Browser.setContrast": Browser.setContrastParameters;
|
||||||
"Browser.setVideoRecordingOptions": Browser.setVideoRecordingOptionsParameters;
|
"Browser.setVideoRecordingOptions": Browser.setVideoRecordingOptionsParameters;
|
||||||
"Browser.cancelDownload": Browser.cancelDownloadParameters;
|
"Browser.cancelDownload": Browser.cancelDownloadParameters;
|
||||||
"Heap.collectGarbage": Heap.collectGarbageParameters;
|
"Heap.collectGarbage": Heap.collectGarbageParameters;
|
||||||
|
|
@ -1213,6 +1220,7 @@ export module Protocol {
|
||||||
"Browser.setColorScheme": Browser.setColorSchemeReturnValue;
|
"Browser.setColorScheme": Browser.setColorSchemeReturnValue;
|
||||||
"Browser.setReducedMotion": Browser.setReducedMotionReturnValue;
|
"Browser.setReducedMotion": Browser.setReducedMotionReturnValue;
|
||||||
"Browser.setForcedColors": Browser.setForcedColorsReturnValue;
|
"Browser.setForcedColors": Browser.setForcedColorsReturnValue;
|
||||||
|
"Browser.setContrast": Browser.setContrastReturnValue;
|
||||||
"Browser.setVideoRecordingOptions": Browser.setVideoRecordingOptionsReturnValue;
|
"Browser.setVideoRecordingOptions": Browser.setVideoRecordingOptionsReturnValue;
|
||||||
"Browser.cancelDownload": Browser.cancelDownloadReturnValue;
|
"Browser.cancelDownload": Browser.cancelDownloadReturnValue;
|
||||||
"Heap.collectGarbage": Heap.collectGarbageReturnValue;
|
"Heap.collectGarbage": Heap.collectGarbageReturnValue;
|
||||||
|
|
|
||||||
|
|
@ -214,12 +214,6 @@ export class HttpServer {
|
||||||
}
|
}
|
||||||
|
|
||||||
private _onRequest(request: http.IncomingMessage, response: http.ServerResponse) {
|
private _onRequest(request: http.IncomingMessage, response: http.ServerResponse) {
|
||||||
response.setHeader('Access-Control-Allow-Origin', '*');
|
|
||||||
response.setHeader('Access-Control-Request-Method', '*');
|
|
||||||
response.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET');
|
|
||||||
if (request.headers.origin)
|
|
||||||
response.setHeader('Access-Control-Allow-Headers', request.headers.origin);
|
|
||||||
|
|
||||||
if (request.method === 'OPTIONS') {
|
if (request.method === 'OPTIONS') {
|
||||||
response.writeHead(200);
|
response.writeHead(200);
|
||||||
response.end();
|
response.end();
|
||||||
|
|
|
||||||
|
|
@ -240,8 +240,8 @@ function validateConfig(file: string, config: Config) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('updateSnapshots' in config && config.updateSnapshots !== undefined) {
|
if ('updateSnapshots' in config && config.updateSnapshots !== undefined) {
|
||||||
if (typeof config.updateSnapshots !== 'string' || !['all', 'none', 'missing'].includes(config.updateSnapshots))
|
if (typeof config.updateSnapshots !== 'string' || !['all', 'changed', 'missing', 'none'].includes(config.updateSnapshots))
|
||||||
throw errorWithFile(file, `config.updateSnapshots must be one of "all", "none" or "missing"`);
|
throw errorWithFile(file, `config.updateSnapshots must be one of "all", "changed", "missing" or "none"`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('workers' in config && config.workers !== undefined) {
|
if ('workers' in config && config.workers !== undefined) {
|
||||||
|
|
|
||||||
|
|
@ -30,12 +30,13 @@ import path from 'path';
|
||||||
type ToMatchAriaSnapshotExpected = {
|
type ToMatchAriaSnapshotExpected = {
|
||||||
name?: string;
|
name?: string;
|
||||||
path?: string;
|
path?: string;
|
||||||
|
timeout?: number;
|
||||||
} | string;
|
} | string;
|
||||||
|
|
||||||
export async function toMatchAriaSnapshot(
|
export async function toMatchAriaSnapshot(
|
||||||
this: ExpectMatcherState,
|
this: ExpectMatcherState,
|
||||||
receiver: LocatorEx,
|
receiver: LocatorEx,
|
||||||
expectedParam: ToMatchAriaSnapshotExpected,
|
expectedParam?: ToMatchAriaSnapshotExpected,
|
||||||
options: { timeout?: number } = {},
|
options: { timeout?: number } = {},
|
||||||
): Promise<MatcherResult<string | RegExp, string>> {
|
): Promise<MatcherResult<string | RegExp, string>> {
|
||||||
const matcherName = 'toMatchAriaSnapshot';
|
const matcherName = 'toMatchAriaSnapshot';
|
||||||
|
|
@ -55,9 +56,11 @@ export async function toMatchAriaSnapshot(
|
||||||
};
|
};
|
||||||
|
|
||||||
let expected: string;
|
let expected: string;
|
||||||
|
let timeout: number;
|
||||||
let expectedPath: string | undefined;
|
let expectedPath: string | undefined;
|
||||||
if (isString(expectedParam)) {
|
if (isString(expectedParam)) {
|
||||||
expected = expectedParam;
|
expected = expectedParam;
|
||||||
|
timeout = options.timeout ?? this.timeout;
|
||||||
} else {
|
} else {
|
||||||
if (expectedParam?.name) {
|
if (expectedParam?.name) {
|
||||||
expectedPath = testInfo.snapshotPath(sanitizeFilePathBeforeExtension(expectedParam.name));
|
expectedPath = testInfo.snapshotPath(sanitizeFilePathBeforeExtension(expectedParam.name));
|
||||||
|
|
@ -71,6 +74,7 @@ export async function toMatchAriaSnapshot(
|
||||||
expectedPath = testInfo.snapshotPath(sanitizeForFilePath(trimLongString(fullTitleWithoutSpec)) + '.yml');
|
expectedPath = testInfo.snapshotPath(sanitizeForFilePath(trimLongString(fullTitleWithoutSpec)) + '.yml');
|
||||||
}
|
}
|
||||||
expected = await fs.promises.readFile(expectedPath, 'utf8').catch(() => '');
|
expected = await fs.promises.readFile(expectedPath, 'utf8').catch(() => '');
|
||||||
|
timeout = expectedParam?.timeout ?? this.timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
const generateMissingBaseline = updateSnapshots === 'missing' && !expected;
|
const generateMissingBaseline = updateSnapshots === 'missing' && !expected;
|
||||||
|
|
@ -84,7 +88,6 @@ export async function toMatchAriaSnapshot(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const timeout = options.timeout ?? this.timeout;
|
|
||||||
expected = unshift(expected);
|
expected = unshift(expected);
|
||||||
const { matches: pass, received, log, timedOut } = await receiver._expect('to.match.aria', { expectedValue: expected, isNot: this.isNot, timeout });
|
const { matches: pass, received, log, timedOut } = await receiver._expect('to.match.aria', { expectedValue: expected, isNot: this.isNot, timeout });
|
||||||
const typedReceived = received as MatcherReceived | typeof kNoElementsFoundError;
|
const typedReceived = received as MatcherReceived | typeof kNoElementsFoundError;
|
||||||
|
|
|
||||||
|
|
@ -286,7 +286,7 @@ function overridesFromOptions(options: { [key: string]: any }): ConfigCLIOverrid
|
||||||
if (['all', 'changed', 'missing', 'none'].includes(options.updateSnapshots))
|
if (['all', 'changed', 'missing', 'none'].includes(options.updateSnapshots))
|
||||||
updateSnapshots = options.updateSnapshots;
|
updateSnapshots = options.updateSnapshots;
|
||||||
else
|
else
|
||||||
updateSnapshots = 'updateSnapshots' in options ? 'changed' : 'missing';
|
updateSnapshots = 'updateSnapshots' in options ? 'changed' : undefined;
|
||||||
|
|
||||||
const overrides: ConfigCLIOverrides = {
|
const overrides: ConfigCLIOverrides = {
|
||||||
forbidOnly: options.forbidOnly ? true : undefined,
|
forbidOnly: options.forbidOnly ? true : undefined,
|
||||||
|
|
|
||||||
1
packages/playwright/types/test.d.ts
vendored
|
|
@ -8690,7 +8690,6 @@ interface LocatorAssertions {
|
||||||
* ```js
|
* ```js
|
||||||
* await expect(page.locator('body')).toMatchAriaSnapshot();
|
* await expect(page.locator('body')).toMatchAriaSnapshot();
|
||||||
* await expect(page.locator('body')).toMatchAriaSnapshot({ name: 'snapshot' });
|
* await expect(page.locator('body')).toMatchAriaSnapshot({ name: 'snapshot' });
|
||||||
* await expect(page.locator('body')).toMatchAriaSnapshot({ path: '/path/to/snapshot.yml' });
|
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* @param options
|
* @param options
|
||||||
|
|
|
||||||
|
|
@ -10,13 +10,13 @@
|
||||||
let textarea = document.querySelector('textarea');
|
let textarea = document.querySelector('textarea');
|
||||||
textarea.focus();
|
textarea.focus();
|
||||||
textarea.addEventListener('keydown', event => {
|
textarea.addEventListener('keydown', event => {
|
||||||
log('Keydown:', event.key, event.code, event.which, modifiers(event));
|
log('Keydown:', event.key, event.code, getLocation(event), modifiers(event));
|
||||||
});
|
});
|
||||||
textarea.addEventListener('keypress', event => {
|
textarea.addEventListener('keypress', event => {
|
||||||
log('Keypress:', event.key, event.code, event.which, event.charCode, modifiers(event));
|
log('Keypress:', event.key, event.code, getLocation(event), event.charCode, modifiers(event));
|
||||||
});
|
});
|
||||||
textarea.addEventListener('keyup', event => {
|
textarea.addEventListener('keyup', event => {
|
||||||
log('Keyup:', event.key, event.code, event.which, modifiers(event));
|
log('Keyup:', event.key, event.code, getLocation(event), modifiers(event));
|
||||||
});
|
});
|
||||||
function modifiers(event) {
|
function modifiers(event) {
|
||||||
let m = [];
|
let m = [];
|
||||||
|
|
@ -28,6 +28,15 @@
|
||||||
m.push('Shift')
|
m.push('Shift')
|
||||||
return '[' + m.join(' ') + ']';
|
return '[' + m.join(' ') + ']';
|
||||||
}
|
}
|
||||||
|
function getLocation(event) {
|
||||||
|
switch (event.location) {
|
||||||
|
case KeyboardEvent.DOM_KEY_LOCATION_STANDARD: return 'STANDARD';
|
||||||
|
case KeyboardEvent.DOM_KEY_LOCATION_LEFT: return 'LEFT';
|
||||||
|
case KeyboardEvent.DOM_KEY_LOCATION_RIGHT: return 'RIGHT';
|
||||||
|
case KeyboardEvent.DOM_KEY_LOCATION_NUMPAD: return 'NUMPAD';
|
||||||
|
default: return 'Unknown: ' + event.location;
|
||||||
|
};
|
||||||
|
}
|
||||||
function log(...args) {
|
function log(...args) {
|
||||||
console.log.apply(console, args);
|
console.log.apply(console, args);
|
||||||
result += args.join(' ') + '\n';
|
result += args.join(' ') + '\n';
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,8 @@ class CsvReporter implements Reporter {
|
||||||
if (test.ok() && !fixme)
|
if (test.ok() && !fixme)
|
||||||
continue;
|
continue;
|
||||||
const row = [];
|
const row = [];
|
||||||
row.push(csvEscape(`${file.title} :: ${test.title}`));
|
const [, , , ...titles] = test.titlePath();
|
||||||
|
row.push(csvEscape(`${file.title} :: ${titles.join(' › ')}`));
|
||||||
row.push(test.expectedStatus);
|
row.push(test.expectedStatus);
|
||||||
row.push(test.outcome());
|
row.push(test.outcome());
|
||||||
if (fixme) {
|
if (fixme) {
|
||||||
|
|
@ -67,7 +68,7 @@ class CsvReporter implements Reporter {
|
||||||
const csv = rows.map(r => r.join(',')).join('\n');
|
const csv = rows.map(r => r.join(',')).join('\n');
|
||||||
const reportFile = path.resolve(this._options.configDir, this._options.outputFile || 'test-results.csv');
|
const reportFile = path.resolve(this._options.configDir, this._options.outputFile || 'test-results.csv');
|
||||||
this._pendingWrite = (async () => {
|
this._pendingWrite = (async () => {
|
||||||
await fs.mkdirSync(path.dirname(reportFile), { recursive: true });
|
await fs.promises.mkdir(path.dirname(reportFile), { recursive: true });
|
||||||
await fs.promises.writeFile(reportFile, csv);
|
await fs.promises.writeFile(reportFile, csv);
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -459,8 +459,13 @@ await page1.GotoAsync("about:blank?foo");`);
|
||||||
const cli = runCLI([`--save-storage=${storageFileName}`, `--save-har=${harFileName}`]);
|
const cli = runCLI([`--save-storage=${storageFileName}`, `--save-har=${harFileName}`]);
|
||||||
await cli.waitFor(`import { test, expect } from '@playwright/test'`);
|
await cli.waitFor(`import { test, expect } from '@playwright/test'`);
|
||||||
await cli.process.kill('SIGINT');
|
await cli.process.kill('SIGINT');
|
||||||
const { exitCode } = await cli.process.exited;
|
const { exitCode, signal } = await cli.process.exited;
|
||||||
expect(exitCode).toBe(130);
|
if (exitCode !== null) {
|
||||||
|
expect(exitCode).toBe(130);
|
||||||
|
} else {
|
||||||
|
// If the runner is slow enough, the process will be forcibly terminated by the signal
|
||||||
|
expect(signal).toBe('SIGINT');
|
||||||
|
}
|
||||||
expect(fs.existsSync(storageFileName)).toBeTruthy();
|
expect(fs.existsSync(storageFileName)).toBeTruthy();
|
||||||
expect(fs.existsSync(harFileName)).toBeTruthy();
|
expect(fs.existsSync(harFileName)).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
After Width: | Height: | Size: 474 B |
|
After Width: | Height: | Size: 138 B |
|
After Width: | Height: | Size: 113 B |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 181 B |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 181 B |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 311 B |
|
After Width: | Height: | Size: 26 KiB |
|
|
@ -41,6 +41,20 @@ it('should fire for fetches', async ({ page, server }) => {
|
||||||
expect(requests.length).toBe(2);
|
expect(requests.length).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should fire for fetches with keepalive: true', {
|
||||||
|
annotation: {
|
||||||
|
type: 'issue',
|
||||||
|
description: 'https://github.com/microsoft/playwright/issues/34497'
|
||||||
|
}
|
||||||
|
}, async ({ page, server, browserName }) => {
|
||||||
|
it.fixme(browserName === 'firefox');
|
||||||
|
const requests = [];
|
||||||
|
page.on('request', request => requests.push(request));
|
||||||
|
await page.goto(server.EMPTY_PAGE);
|
||||||
|
await page.evaluate(() => fetch('/empty.html', { keepalive: true }));
|
||||||
|
expect(requests.length).toBe(2);
|
||||||
|
});
|
||||||
|
|
||||||
it('should report requests and responses handled by service worker', async ({ page, server, isAndroid, isElectron }) => {
|
it('should report requests and responses handled by service worker', async ({ page, server, isAndroid, isElectron }) => {
|
||||||
it.fixme(isAndroid);
|
it.fixme(isAndroid);
|
||||||
it.fixme(isElectron);
|
it.fixme(isElectron);
|
||||||
|
|
|
||||||
|
|
@ -93,18 +93,18 @@ it('should report shiftKey', async ({ page, server, browserName, platform }) =>
|
||||||
const codeForKey = { 'Shift': 16, 'Alt': 18, 'Control': 17 };
|
const codeForKey = { 'Shift': 16, 'Alt': 18, 'Control': 17 };
|
||||||
for (const modifierKey in codeForKey) {
|
for (const modifierKey in codeForKey) {
|
||||||
await keyboard.down(modifierKey);
|
await keyboard.down(modifierKey);
|
||||||
expect(await page.evaluate('getResult()')).toBe('Keydown: ' + modifierKey + ' ' + modifierKey + 'Left ' + codeForKey[modifierKey] + ' [' + modifierKey + ']');
|
expect(await page.evaluate('getResult()')).toBe('Keydown: ' + modifierKey + ' ' + modifierKey + 'Left LEFT [' + modifierKey + ']');
|
||||||
await keyboard.down('!');
|
await keyboard.down('!');
|
||||||
// Shift+! will generate a keypress
|
// Shift+! will generate a keypress
|
||||||
if (modifierKey === 'Shift')
|
if (modifierKey === 'Shift')
|
||||||
expect(await page.evaluate('getResult()')).toBe('Keydown: ! Digit1 49 [' + modifierKey + ']\nKeypress: ! Digit1 33 33 [' + modifierKey + ']');
|
expect(await page.evaluate('getResult()')).toBe('Keydown: ! Digit1 STANDARD [' + modifierKey + ']\nKeypress: ! Digit1 STANDARD 33 [' + modifierKey + ']');
|
||||||
else
|
else
|
||||||
expect(await page.evaluate('getResult()')).toBe('Keydown: ! Digit1 49 [' + modifierKey + ']');
|
expect(await page.evaluate('getResult()')).toBe('Keydown: ! Digit1 STANDARD [' + modifierKey + ']');
|
||||||
|
|
||||||
await keyboard.up('!');
|
await keyboard.up('!');
|
||||||
expect(await page.evaluate('getResult()')).toBe('Keyup: ! Digit1 49 [' + modifierKey + ']');
|
expect(await page.evaluate('getResult()')).toBe('Keyup: ! Digit1 STANDARD [' + modifierKey + ']');
|
||||||
await keyboard.up(modifierKey);
|
await keyboard.up(modifierKey);
|
||||||
expect(await page.evaluate('getResult()')).toBe('Keyup: ' + modifierKey + ' ' + modifierKey + 'Left ' + codeForKey[modifierKey] + ' []');
|
expect(await page.evaluate('getResult()')).toBe('Keyup: ' + modifierKey + ' ' + modifierKey + 'Left LEFT []');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -112,31 +112,31 @@ it('should report multiple modifiers', async ({ page, server }) => {
|
||||||
await page.goto(server.PREFIX + '/input/keyboard.html');
|
await page.goto(server.PREFIX + '/input/keyboard.html');
|
||||||
const keyboard = page.keyboard;
|
const keyboard = page.keyboard;
|
||||||
await keyboard.down('Control');
|
await keyboard.down('Control');
|
||||||
expect(await page.evaluate('getResult()')).toBe('Keydown: Control ControlLeft 17 [Control]');
|
expect(await page.evaluate('getResult()')).toBe('Keydown: Control ControlLeft LEFT [Control]');
|
||||||
await keyboard.down('Alt');
|
await keyboard.down('Alt');
|
||||||
expect(await page.evaluate('getResult()')).toBe('Keydown: Alt AltLeft 18 [Alt Control]');
|
expect(await page.evaluate('getResult()')).toBe('Keydown: Alt AltLeft LEFT [Alt Control]');
|
||||||
await keyboard.down(';');
|
await keyboard.down(';');
|
||||||
expect(await page.evaluate('getResult()')).toBe('Keydown: ; Semicolon 186 [Alt Control]');
|
expect(await page.evaluate('getResult()')).toBe('Keydown: ; Semicolon STANDARD [Alt Control]');
|
||||||
await keyboard.up(';');
|
await keyboard.up(';');
|
||||||
expect(await page.evaluate('getResult()')).toBe('Keyup: ; Semicolon 186 [Alt Control]');
|
expect(await page.evaluate('getResult()')).toBe('Keyup: ; Semicolon STANDARD [Alt Control]');
|
||||||
await keyboard.up('Control');
|
await keyboard.up('Control');
|
||||||
expect(await page.evaluate('getResult()')).toBe('Keyup: Control ControlLeft 17 [Alt]');
|
expect(await page.evaluate('getResult()')).toBe('Keyup: Control ControlLeft LEFT [Alt]');
|
||||||
await keyboard.up('Alt');
|
await keyboard.up('Alt');
|
||||||
expect(await page.evaluate('getResult()')).toBe('Keyup: Alt AltLeft 18 []');
|
expect(await page.evaluate('getResult()')).toBe('Keyup: Alt AltLeft LEFT []');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should send proper codes while typing', async ({ page, server }) => {
|
it('should send proper codes while typing', async ({ page, server }) => {
|
||||||
await page.goto(server.PREFIX + '/input/keyboard.html');
|
await page.goto(server.PREFIX + '/input/keyboard.html');
|
||||||
await page.keyboard.type('!');
|
await page.keyboard.type('!');
|
||||||
expect(await page.evaluate('getResult()')).toBe(
|
expect(await page.evaluate('getResult()')).toBe(
|
||||||
['Keydown: ! Digit1 49 []',
|
['Keydown: ! Digit1 STANDARD []',
|
||||||
'Keypress: ! Digit1 33 33 []',
|
'Keypress: ! Digit1 STANDARD 33 []',
|
||||||
'Keyup: ! Digit1 49 []'].join('\n'));
|
'Keyup: ! Digit1 STANDARD []'].join('\n'));
|
||||||
await page.keyboard.type('^');
|
await page.keyboard.type('^');
|
||||||
expect(await page.evaluate('getResult()')).toBe(
|
expect(await page.evaluate('getResult()')).toBe(
|
||||||
['Keydown: ^ Digit6 54 []',
|
['Keydown: ^ Digit6 STANDARD []',
|
||||||
'Keypress: ^ Digit6 94 94 []',
|
'Keypress: ^ Digit6 STANDARD 94 []',
|
||||||
'Keyup: ^ Digit6 54 []'].join('\n'));
|
'Keyup: ^ Digit6 STANDARD []'].join('\n'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should send proper codes while typing with shift', async ({ page, server }) => {
|
it('should send proper codes while typing with shift', async ({ page, server }) => {
|
||||||
|
|
@ -145,10 +145,10 @@ it('should send proper codes while typing with shift', async ({ page, server })
|
||||||
await keyboard.down('Shift');
|
await keyboard.down('Shift');
|
||||||
await page.keyboard.type('~');
|
await page.keyboard.type('~');
|
||||||
expect(await page.evaluate('getResult()')).toBe(
|
expect(await page.evaluate('getResult()')).toBe(
|
||||||
['Keydown: Shift ShiftLeft 16 [Shift]',
|
['Keydown: Shift ShiftLeft LEFT [Shift]',
|
||||||
'Keydown: ~ Backquote 192 [Shift]', // 192 is ` keyCode
|
'Keydown: ~ Backquote STANDARD [Shift]',
|
||||||
'Keypress: ~ Backquote 126 126 [Shift]', // 126 is ~ charCode
|
'Keypress: ~ Backquote STANDARD 126 [Shift]',
|
||||||
'Keyup: ~ Backquote 192 [Shift]'].join('\n'));
|
'Keyup: ~ Backquote STANDARD [Shift]'].join('\n'));
|
||||||
await keyboard.up('Shift');
|
await keyboard.up('Shift');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -173,54 +173,54 @@ it('should press plus', async ({ page, server }) => {
|
||||||
await page.goto(server.PREFIX + '/input/keyboard.html');
|
await page.goto(server.PREFIX + '/input/keyboard.html');
|
||||||
await page.keyboard.press('+');
|
await page.keyboard.press('+');
|
||||||
expect(await page.evaluate('getResult()')).toBe(
|
expect(await page.evaluate('getResult()')).toBe(
|
||||||
['Keydown: + Equal 187 []', // 192 is ` keyCode
|
['Keydown: + Equal STANDARD []',
|
||||||
'Keypress: + Equal 43 43 []', // 126 is ~ charCode
|
'Keypress: + Equal STANDARD 43 []',
|
||||||
'Keyup: + Equal 187 []'].join('\n'));
|
'Keyup: + Equal STANDARD []'].join('\n'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should press shift plus', async ({ page, server }) => {
|
it('should press shift plus', async ({ page, server }) => {
|
||||||
await page.goto(server.PREFIX + '/input/keyboard.html');
|
await page.goto(server.PREFIX + '/input/keyboard.html');
|
||||||
await page.keyboard.press('Shift++');
|
await page.keyboard.press('Shift++');
|
||||||
expect(await page.evaluate('getResult()')).toBe(
|
expect(await page.evaluate('getResult()')).toBe(
|
||||||
['Keydown: Shift ShiftLeft 16 [Shift]',
|
['Keydown: Shift ShiftLeft LEFT [Shift]',
|
||||||
'Keydown: + Equal 187 [Shift]', // 192 is ` keyCode
|
'Keydown: + Equal STANDARD [Shift]',
|
||||||
'Keypress: + Equal 43 43 [Shift]', // 126 is ~ charCode
|
'Keypress: + Equal STANDARD 43 [Shift]',
|
||||||
'Keyup: + Equal 187 [Shift]',
|
'Keyup: + Equal STANDARD [Shift]',
|
||||||
'Keyup: Shift ShiftLeft 16 []'].join('\n'));
|
'Keyup: Shift ShiftLeft LEFT []'].join('\n'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should support plus-separated modifiers', async ({ page, server }) => {
|
it('should support plus-separated modifiers', async ({ page, server }) => {
|
||||||
await page.goto(server.PREFIX + '/input/keyboard.html');
|
await page.goto(server.PREFIX + '/input/keyboard.html');
|
||||||
await page.keyboard.press('Shift+~');
|
await page.keyboard.press('Shift+~');
|
||||||
expect(await page.evaluate('getResult()')).toBe(
|
expect(await page.evaluate('getResult()')).toBe(
|
||||||
['Keydown: Shift ShiftLeft 16 [Shift]',
|
['Keydown: Shift ShiftLeft LEFT [Shift]',
|
||||||
'Keydown: ~ Backquote 192 [Shift]', // 192 is ` keyCode
|
'Keydown: ~ Backquote STANDARD [Shift]',
|
||||||
'Keypress: ~ Backquote 126 126 [Shift]', // 126 is ~ charCode
|
'Keypress: ~ Backquote STANDARD 126 [Shift]',
|
||||||
'Keyup: ~ Backquote 192 [Shift]',
|
'Keyup: ~ Backquote STANDARD [Shift]',
|
||||||
'Keyup: Shift ShiftLeft 16 []'].join('\n'));
|
'Keyup: Shift ShiftLeft LEFT []'].join('\n'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should support multiple plus-separated modifiers', async ({ page, server }) => {
|
it('should support multiple plus-separated modifiers', async ({ page, server }) => {
|
||||||
await page.goto(server.PREFIX + '/input/keyboard.html');
|
await page.goto(server.PREFIX + '/input/keyboard.html');
|
||||||
await page.keyboard.press('Control+Shift+~');
|
await page.keyboard.press('Control+Shift+~');
|
||||||
expect(await page.evaluate('getResult()')).toBe(
|
expect(await page.evaluate('getResult()')).toBe(
|
||||||
['Keydown: Control ControlLeft 17 [Control]',
|
['Keydown: Control ControlLeft LEFT [Control]',
|
||||||
'Keydown: Shift ShiftLeft 16 [Control Shift]',
|
'Keydown: Shift ShiftLeft LEFT [Control Shift]',
|
||||||
'Keydown: ~ Backquote 192 [Control Shift]', // 192 is ` keyCode
|
'Keydown: ~ Backquote STANDARD [Control Shift]',
|
||||||
'Keyup: ~ Backquote 192 [Control Shift]',
|
'Keyup: ~ Backquote STANDARD [Control Shift]',
|
||||||
'Keyup: Shift ShiftLeft 16 [Control]',
|
'Keyup: Shift ShiftLeft LEFT [Control]',
|
||||||
'Keyup: Control ControlLeft 17 []'].join('\n'));
|
'Keyup: Control ControlLeft LEFT []'].join('\n'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should shift raw codes', async ({ page, server }) => {
|
it('should shift raw codes', async ({ page, server }) => {
|
||||||
await page.goto(server.PREFIX + '/input/keyboard.html');
|
await page.goto(server.PREFIX + '/input/keyboard.html');
|
||||||
await page.keyboard.press('Shift+Digit3');
|
await page.keyboard.press('Shift+Digit3');
|
||||||
expect(await page.evaluate('getResult()')).toBe(
|
expect(await page.evaluate('getResult()')).toBe(
|
||||||
['Keydown: Shift ShiftLeft 16 [Shift]',
|
['Keydown: Shift ShiftLeft LEFT [Shift]',
|
||||||
'Keydown: # Digit3 51 [Shift]', // 51 is # keyCode
|
'Keydown: # Digit3 STANDARD [Shift]',
|
||||||
'Keypress: # Digit3 35 35 [Shift]', // 35 is # charCode
|
'Keypress: # Digit3 STANDARD 35 [Shift]',
|
||||||
'Keyup: # Digit3 51 [Shift]',
|
'Keyup: # Digit3 STANDARD [Shift]',
|
||||||
'Keyup: Shift ShiftLeft 16 []'].join('\n'));
|
'Keyup: Shift ShiftLeft LEFT []'].join('\n'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should specify repeat property', async ({ page, server }) => {
|
it('should specify repeat property', async ({ page, server }) => {
|
||||||
|
|
@ -710,7 +710,7 @@ it('should have correct Keydown/Keyup order when pressing Escape key', async ({
|
||||||
await page.goto(server.PREFIX + '/input/keyboard.html');
|
await page.goto(server.PREFIX + '/input/keyboard.html');
|
||||||
await page.keyboard.press('Escape');
|
await page.keyboard.press('Escape');
|
||||||
expect(await page.evaluate('getResult()')).toBe(`
|
expect(await page.evaluate('getResult()')).toBe(`
|
||||||
Keydown: Escape Escape 27 []
|
Keydown: Escape Escape STANDARD []
|
||||||
Keyup: Escape Escape 27 []
|
Keyup: Escape Escape STANDARD []
|
||||||
`.trim());
|
`.trim());
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -152,3 +152,60 @@ test('should generate snapshot name', async ({ runInlineTest }, testInfo) => {
|
||||||
const snapshot2 = await fs.promises.readFile(testInfo.outputPath('__snapshots__/a.spec.ts/test-name-2.yml'), 'utf8');
|
const snapshot2 = await fs.promises.readFile(testInfo.outputPath('__snapshots__/a.spec.ts/test-name-2.yml'), 'utf8');
|
||||||
expect(snapshot2).toBe('- heading "hello world 2" [level=1]');
|
expect(snapshot2).toBe('- heading "hello world 2" [level=1]');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
for (const updateSnapshots of ['all', 'changed', 'missing', 'none']) {
|
||||||
|
test(`should update snapshot with the update-snapshots=${updateSnapshots} (config)`, async ({ runInlineTest }, testInfo) => {
|
||||||
|
const result = await runInlineTest({
|
||||||
|
'playwright.config.ts': `
|
||||||
|
export default {
|
||||||
|
snapshotPathTemplate: '__snapshots__/{testFilePath}/{arg}{ext}',
|
||||||
|
updateSnapshots: '${updateSnapshots}',
|
||||||
|
};
|
||||||
|
`,
|
||||||
|
'a.spec.ts': `
|
||||||
|
import { test, expect } from '@playwright/test';
|
||||||
|
test('test', async ({ page }) => {
|
||||||
|
await page.setContent(\`<h1>New content</h1>\`);
|
||||||
|
await expect(page.locator('body')).toMatchAriaSnapshot({ timeout: 1 });
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
'__snapshots__/a.spec.ts/test-1.yml': '- heading "Old content" [level=1]',
|
||||||
|
});
|
||||||
|
|
||||||
|
const rebase = updateSnapshots === 'all' || updateSnapshots === 'changed';
|
||||||
|
expect(result.exitCode).toBe(rebase ? 0 : 1);
|
||||||
|
if (rebase) {
|
||||||
|
const snapshotOutputPath = testInfo.outputPath('__snapshots__/a.spec.ts/test-1.yml');
|
||||||
|
expect(result.output).toContain(`A snapshot is generated at`);
|
||||||
|
const data = fs.readFileSync(snapshotOutputPath);
|
||||||
|
expect(data.toString()).toBe('- heading "New content" [level=1]');
|
||||||
|
} else {
|
||||||
|
expect(result.output).toContain(`expect.toMatchAriaSnapshot`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
test('should respect timeout', async ({ runInlineTest }, testInfo) => {
|
||||||
|
const result = await runInlineTest({
|
||||||
|
'playwright.config.ts': `
|
||||||
|
export default {
|
||||||
|
snapshotPathTemplate: '__snapshots__/{testFilePath}/{arg}{ext}',
|
||||||
|
};
|
||||||
|
`,
|
||||||
|
'test.yml': `
|
||||||
|
- heading "hello world"
|
||||||
|
`,
|
||||||
|
'a.spec.ts': `
|
||||||
|
import { test, expect } from '@playwright/test';
|
||||||
|
import path from 'path';
|
||||||
|
test('test', async ({ page }) => {
|
||||||
|
await page.setContent(\`<h1>hello world</h1>\`);
|
||||||
|
await expect(page.locator('body')).toMatchAriaSnapshot({ timeout: 1 });
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
'__snapshots__/a.spec.ts/test-1.yml': '- heading "new world" [level=1]',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.exitCode).toBe(1);
|
||||||
|
expect(result.output).toContain(`Timed out 1ms waiting for`);
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -341,6 +341,36 @@ test('should update snapshot with the update-snapshots flag', async ({ runInline
|
||||||
expect(data.toString()).toBe(ACTUAL_SNAPSHOT);
|
expect(data.toString()).toBe(ACTUAL_SNAPSHOT);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
for (const updateSnapshots of ['all', 'changed', 'missing', 'none']) {
|
||||||
|
test(`should update snapshot with the update-snapshots=${updateSnapshots} (config)`, async ({ runInlineTest }, testInfo) => {
|
||||||
|
const result = await runInlineTest({
|
||||||
|
'playwright.config.ts': `export default { updateSnapshots: '${updateSnapshots}' };`,
|
||||||
|
...files,
|
||||||
|
'a.spec.js-snapshots/snapshot.txt': 'Hello world',
|
||||||
|
'a.spec.js': `
|
||||||
|
const { test, expect } = require('./helper');
|
||||||
|
test('is a test', ({}) => {
|
||||||
|
expect('Hello world updated').toMatchSnapshot('snapshot.txt');
|
||||||
|
});
|
||||||
|
`
|
||||||
|
});
|
||||||
|
|
||||||
|
const rebase = updateSnapshots === 'all' || updateSnapshots === 'changed';
|
||||||
|
expect(result.exitCode).toBe(rebase ? 0 : 1);
|
||||||
|
if (rebase) {
|
||||||
|
const snapshotOutputPath = testInfo.outputPath('a.spec.js-snapshots/snapshot.txt');
|
||||||
|
if (updateSnapshots === 'all')
|
||||||
|
expect(result.output).toContain(`${snapshotOutputPath} is not the same, writing actual.`);
|
||||||
|
if (updateSnapshots === 'changed')
|
||||||
|
expect(result.output).toContain(`${snapshotOutputPath} does not match, writing actual.`);
|
||||||
|
const data = fs.readFileSync(snapshotOutputPath);
|
||||||
|
expect(data.toString()).toBe('Hello world updated');
|
||||||
|
} else {
|
||||||
|
expect(result.output).toContain(`toMatchSnapshot`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
test('should ignore text snapshot with the ignore-snapshots flag', async ({ runInlineTest }, testInfo) => {
|
test('should ignore text snapshot with the ignore-snapshots flag', async ({ runInlineTest }, testInfo) => {
|
||||||
const EXPECTED_SNAPSHOT = 'Hello world';
|
const EXPECTED_SNAPSHOT = 'Hello world';
|
||||||
const ACTUAL_SNAPSHOT = 'Hello world updated';
|
const ACTUAL_SNAPSHOT = 'Hello world updated';
|
||||||
|
|
@ -1140,3 +1170,25 @@ test('should throw if a Promise was passed to toMatchSnapshot', async ({ runInli
|
||||||
expect(result.exitCode).toBe(0);
|
expect(result.exitCode).toBe(0);
|
||||||
expect(result.passed).toBe(1);
|
expect(result.passed).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
test('should respect update snapshot option from config', async ({ runInlineTest }, testInfo) => {
|
||||||
|
const EXPECTED_SNAPSHOT = 'Hello world';
|
||||||
|
const ACTUAL_SNAPSHOT = 'Hello world updated';
|
||||||
|
const result = await runInlineTest({
|
||||||
|
...files,
|
||||||
|
'a.spec.js-snapshots/snapshot.txt': EXPECTED_SNAPSHOT,
|
||||||
|
'a.spec.js': `
|
||||||
|
const { test, expect } = require('./helper');
|
||||||
|
test('is a test', ({}) => {
|
||||||
|
expect('${ACTUAL_SNAPSHOT}').toMatchSnapshot('snapshot.txt');
|
||||||
|
});
|
||||||
|
`
|
||||||
|
}, { 'update-snapshots': true });
|
||||||
|
|
||||||
|
expect(result.exitCode).toBe(0);
|
||||||
|
const snapshotOutputPath = testInfo.outputPath('a.spec.js-snapshots/snapshot.txt');
|
||||||
|
expect(result.output).toContain(`${snapshotOutputPath} does not match, writing actual.`);
|
||||||
|
const data = fs.readFileSync(snapshotOutputPath);
|
||||||
|
expect(data.toString()).toBe(ACTUAL_SNAPSHOT);
|
||||||
|
});
|
||||||
|
|
|
||||||