Merge branch 'main' into ui-mode-watch-file
This commit is contained in:
commit
975513e3d9
|
|
@ -30,6 +30,7 @@ module.exports = {
|
|||
"avoidEscape": true,
|
||||
"allowTemplateLiterals": true
|
||||
}],
|
||||
"jsx-quotes": [2, "prefer-single"],
|
||||
"no-extra-semi": 2,
|
||||
"@typescript-eslint/semi": [2],
|
||||
"comma-style": [2, "last"],
|
||||
|
|
|
|||
1
.github/workflows/tests_primary.yml
vendored
1
.github/workflows/tests_primary.yml
vendored
|
|
@ -219,7 +219,6 @@ jobs:
|
|||
with:
|
||||
command: npm run itest
|
||||
bot-name: "package-installations-${{ matrix.os }}"
|
||||
# TODO: figure out why itest fails with 'bash' on Windows.
|
||||
shell: ${{ matrix.os == 'windows-latest' && 'pwsh' || 'bash' }}
|
||||
flakiness-client-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_CLIENT_ID }}
|
||||
flakiness-tenant-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_TENANT_ID }}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# 🎭 Playwright
|
||||
|
||||
[](https://www.npmjs.com/package/playwright) <!-- GEN:chromium-version-badge -->[](https://www.chromium.org/Home)<!-- GEN:stop --> <!-- GEN:firefox-version-badge -->[](https://www.mozilla.org/en-US/firefox/new/)<!-- GEN:stop --> <!-- GEN:webkit-version-badge -->[](https://webkit.org/)<!-- GEN:stop -->
|
||||
[](https://www.npmjs.com/package/playwright) <!-- GEN:chromium-version-badge -->[](https://www.chromium.org/Home)<!-- GEN:stop --> <!-- GEN:firefox-version-badge -->[](https://www.mozilla.org/en-US/firefox/new/)<!-- GEN:stop --> <!-- GEN:webkit-version-badge -->[](https://webkit.org/)<!-- GEN:stop -->
|
||||
|
||||
## [Documentation](https://playwright.dev) | [API reference](https://playwright.dev/docs/api/class-playwright)
|
||||
|
||||
|
|
@ -8,8 +8,8 @@ Playwright is a framework for Web Testing and Automation. It allows testing [Chr
|
|||
|
||||
| | Linux | macOS | Windows |
|
||||
| :--- | :---: | :---: | :---: |
|
||||
| Chromium <!-- GEN:chromium-version -->127.0.6533.57<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||
| WebKit <!-- GEN:webkit-version -->17.4<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||
| Chromium <!-- GEN:chromium-version -->128.0.6613.7<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||
| WebKit <!-- GEN:webkit-version -->18.0<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||
| Firefox <!-- GEN:firefox-version -->128.0<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||
|
||||
Headless execution is supported for all browsers on all platforms. Check out [system requirements](https://playwright.dev/docs/intro#system-requirements) for details.
|
||||
|
|
|
|||
|
|
@ -523,7 +523,7 @@ Does not enforce fixed viewport, allows resizing window in the headed mode.
|
|||
|
||||
## context-option-clientCertificates
|
||||
- `clientCertificates` <[Array]<[Object]>>
|
||||
- `origin` <[string]> Glob pattern to match against the request origin that the certificate is valid for.
|
||||
- `origin` <[string]> Exact origin that the certificate is valid for. Origin includes `https` protocol, a hostname and optionally a port.
|
||||
- `certPath` ?<[string]> Path to the file with the certificate in PEM format.
|
||||
- `keyPath` ?<[string]> Path to the file with the private key in PEM format.
|
||||
- `pfxPath` ?<[string]> Path to the PFX or PKCS12 encoded private key and certificate chain.
|
||||
|
|
@ -533,7 +533,7 @@ TLS Client Authentication allows the server to request a client certificate and
|
|||
|
||||
**Details**
|
||||
|
||||
An array of client certificates to be used. Each certificate object must have both `certPath` and `keyPath` or a single `pfxPath` to load the client certificate. Optionally, `passphrase` property should be provided if the certficiate is encrypted. If the certificate is valid only for specific origins, the `origin` property should be provided with a glob pattern to match the origins that the certificate is valid for.
|
||||
An array of client certificates to be used. Each certificate object must have both `certPath` and `keyPath` or a single `pfxPath` to load the client certificate. Optionally, `passphrase` property should be provided if the certficiate is encrypted. The `origin` property should be provided with an exact match to the request origin that the certificate is valid for.
|
||||
|
||||
:::note
|
||||
Using Client Certificates in combination with Proxy Servers is not supported.
|
||||
|
|
|
|||
|
|
@ -386,7 +386,7 @@ jobs:
|
|||
### Fail-Fast
|
||||
* langs: js
|
||||
|
||||
Even with sharding enabled, large test suites can take very long to execute. Running changed tests first on PRs will give you a faster feedback loop and use less CI resources.
|
||||
Even with sharding enabled, large test suites can take very long to execute. Running changed test files first on PRs will give you a faster feedback loop and use less CI resources.
|
||||
|
||||
```yml js title=".github/workflows/playwright.yml"
|
||||
name: Playwright Tests
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ Complete set of Playwright Test options is available in the [configuration file]
|
|||
| `--max-failures <N>` or `-x`| Stop after the first `N` test failures. Passing `-x` stops after the first failure.|
|
||||
| `--no-deps` | Ignore the dependencies between projects and behave as if they were not specified. |
|
||||
| `--output <dir>` | Directory for artifacts produced by tests, defaults to `test-results`. |
|
||||
| `--only-changed [ref]` | Only run tests that have been changed between working tree and "ref". Defaults to running all uncommitted changes with ref=HEAD. Only supports Git. |
|
||||
| `--only-changed [ref]` | Only run test files that have been changed between working tree and "ref". Defaults to running all uncommitted changes with ref=HEAD. Only supports Git. |
|
||||
| `--pass-with-no-tests` | Allows the test suite to pass when no files are found. |
|
||||
| `--project <name>` | Only run tests from the specified [projects](./test-projects.md), supports '*' wildcard. Defaults to running all projects defined in the configuration file.|
|
||||
| `--quiet` | Whether to suppress stdout and stderr from the tests. |
|
||||
|
|
|
|||
|
|
@ -70,36 +70,36 @@ export const blank = () => {
|
|||
};
|
||||
|
||||
export const externalLink = () => {
|
||||
return <svg className='octicon' viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M10.604 1h4.146a.25.25 0 01.25.25v4.146a.25.25 0 01-.427.177L13.03 4.03 9.28 7.78a.75.75 0 01-1.06-1.06l3.75-3.75-1.543-1.543A.25.25 0 0110.604 1zM3.75 2A1.75 1.75 0 002 3.75v8.5c0 .966.784 1.75 1.75 1.75h8.5A1.75 1.75 0 0014 12.25v-3.5a.75.75 0 00-1.5 0v3.5a.25.25 0 01-.25.25h-8.5a.25.25 0 01-.25-.25v-8.5a.25.25 0 01.25-.25h3.5a.75.75 0 000-1.5h-3.5z"></path></svg>;
|
||||
return <svg className='octicon' viewBox='0 0 16 16' width='16' height='16'><path fill-rule='evenodd' d='M10.604 1h4.146a.25.25 0 01.25.25v4.146a.25.25 0 01-.427.177L13.03 4.03 9.28 7.78a.75.75 0 01-1.06-1.06l3.75-3.75-1.543-1.543A.25.25 0 0110.604 1zM3.75 2A1.75 1.75 0 002 3.75v8.5c0 .966.784 1.75 1.75 1.75h8.5A1.75 1.75 0 0014 12.25v-3.5a.75.75 0 00-1.5 0v3.5a.25.25 0 01-.25.25h-8.5a.25.25 0 01-.25-.25v-8.5a.25.25 0 01.25-.25h3.5a.75.75 0 000-1.5h-3.5z'></path></svg>;
|
||||
};
|
||||
|
||||
export const calendar = () => {
|
||||
return <svg className='octicon' viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M4.75 0a.75.75 0 01.75.75V2h5V.75a.75.75 0 011.5 0V2h1.25c.966 0 1.75.784 1.75 1.75v10.5A1.75 1.75 0 0113.25 16H2.75A1.75 1.75 0 011 14.25V3.75C1 2.784 1.784 2 2.75 2H4V.75A.75.75 0 014.75 0zm0 3.5h8.5a.25.25 0 01.25.25V6h-11V3.75a.25.25 0 01.25-.25h2zm-2.25 4v6.75c0 .138.112.25.25.25h10.5a.25.25 0 00.25-.25V7.5h-11z"></path></svg>;
|
||||
return <svg className='octicon' viewBox='0 0 16 16' width='16' height='16'><path fill-rule='evenodd' d='M4.75 0a.75.75 0 01.75.75V2h5V.75a.75.75 0 011.5 0V2h1.25c.966 0 1.75.784 1.75 1.75v10.5A1.75 1.75 0 0113.25 16H2.75A1.75 1.75 0 011 14.25V3.75C1 2.784 1.784 2 2.75 2H4V.75A.75.75 0 014.75 0zm0 3.5h8.5a.25.25 0 01.25.25V6h-11V3.75a.25.25 0 01.25-.25h2zm-2.25 4v6.75c0 .138.112.25.25.25h10.5a.25.25 0 00.25-.25V7.5h-11z'></path></svg>;
|
||||
};
|
||||
|
||||
export const person = () => {
|
||||
return <svg className='octicon' viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M10.5 5a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0zm.061 3.073a4 4 0 10-5.123 0 6.004 6.004 0 00-3.431 5.142.75.75 0 001.498.07 4.5 4.5 0 018.99 0 .75.75 0 101.498-.07 6.005 6.005 0 00-3.432-5.142z"></path></svg>;
|
||||
return <svg className='octicon' viewBox='0 0 16 16' width='16' height='16'><path fill-rule='evenodd' d='M10.5 5a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0zm.061 3.073a4 4 0 10-5.123 0 6.004 6.004 0 00-3.431 5.142.75.75 0 001.498.07 4.5 4.5 0 018.99 0 .75.75 0 101.498-.07 6.005 6.005 0 00-3.432-5.142z'></path></svg>;
|
||||
};
|
||||
|
||||
export const commit = () => {
|
||||
return <svg className='octicon' viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M10.5 7.75a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0zm1.43.75a4.002 4.002 0 01-7.86 0H.75a.75.75 0 110-1.5h3.32a4.001 4.001 0 017.86 0h3.32a.75.75 0 110 1.5h-3.32z"></path></svg>;
|
||||
return <svg className='octicon' viewBox='0 0 16 16' width='16' height='16'><path fill-rule='evenodd' d='M10.5 7.75a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0zm1.43.75a4.002 4.002 0 01-7.86 0H.75a.75.75 0 110-1.5h3.32a4.001 4.001 0 017.86 0h3.32a.75.75 0 110 1.5h-3.32z'></path></svg>;
|
||||
};
|
||||
|
||||
export const image = () => {
|
||||
return <svg className='octicon' viewBox='0 0 48 48' version='1.1' width='20' height='20' aria-hidden='true'>
|
||||
<path xmlns="http://www.w3.org/2000/svg" d="M11.85 32H36.2l-7.35-9.95-6.55 8.7-4.6-6.45ZM7 40q-1.2 0-2.1-.9Q4 38.2 4 37V11q0-1.2.9-2.1Q5.8 8 7 8h34q1.2 0 2.1.9.9.9.9 2.1v26q0 1.2-.9 2.1-.9.9-2.1.9Zm0-29v26-26Zm34 26V11H7v26Z"/>
|
||||
<path xmlns='http://www.w3.org/2000/svg' d='M11.85 32H36.2l-7.35-9.95-6.55 8.7-4.6-6.45ZM7 40q-1.2 0-2.1-.9Q4 38.2 4 37V11q0-1.2.9-2.1Q5.8 8 7 8h34q1.2 0 2.1.9.9.9.9 2.1v26q0 1.2-.9 2.1-.9.9-2.1.9Zm0-29v26-26Zm34 26V11H7v26Z'/>
|
||||
</svg>;
|
||||
};
|
||||
|
||||
export const video = () => {
|
||||
return <svg className='octicon' viewBox='0 0 48 48' version='1.1' width='20' height='20' aria-hidden='true'>
|
||||
<path xmlns="http://www.w3.org/2000/svg" d="m19.6 32.35 13-8.45-13-8.45ZM7 40q-1.2 0-2.1-.9Q4 38.2 4 37V11q0-1.2.9-2.1Q5.8 8 7 8h34q1.2 0 2.1.9.9.9.9 2.1v26q0 1.2-.9 2.1-.9.9-2.1.9Zm0-3h34V11H7v26Zm0 0V11v26Z"/>
|
||||
<path xmlns='http://www.w3.org/2000/svg' d='m19.6 32.35 13-8.45-13-8.45ZM7 40q-1.2 0-2.1-.9Q4 38.2 4 37V11q0-1.2.9-2.1Q5.8 8 7 8h34q1.2 0 2.1.9.9.9.9 2.1v26q0 1.2-.9 2.1-.9.9-2.1.9Zm0-3h34V11H7v26Zm0 0V11v26Z'/>
|
||||
</svg>;
|
||||
};
|
||||
|
||||
export const trace = () => {
|
||||
return <svg className='octicon' viewBox='0 0 48 48' version='1.1' width='20' height='20' aria-hidden='true'>
|
||||
<path xmlns="http://www.w3.org/2000/svg" d="M7 37h9.35V11H7v26Zm12.35 0h9.3V11h-9.3v26Zm12.3 0H41V11h-9.35v26ZM7 40q-1.2 0-2.1-.9Q4 38.2 4 37V11q0-1.2.9-2.1Q5.8 8 7 8h34q1.2 0 2.1.9.9.9.9 2.1v26q0 1.2-.9 2.1-.9.9-2.1.9Z"/>
|
||||
<path xmlns='http://www.w3.org/2000/svg' d='M7 37h9.35V11H7v26Zm12.35 0h9.3V11h-9.3v26Zm12.3 0H41V11h-9.35v26ZM7 40q-1.2 0-2.1-.9Q4 38.2 4 37V11q0-1.2.9-2.1Q5.8 8 7 8h34q1.2 0 2.1.9.9.9.9 2.1v26q0 1.2-.9 2.1-.9.9-2.1.9Z'/>
|
||||
</svg>;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ export const TestFileView: React.FC<React.PropsWithChildren<{
|
|||
{file.tests.filter(t => filter.matches(t)).map(test =>
|
||||
<div key={`test-${test.testId}`} className={'test-file-test test-file-test-outcome-' + test.outcome}>
|
||||
<div className='hbox' style={{ alignItems: 'flex-start' }}>
|
||||
<div className="hbox">
|
||||
<span className="test-file-test-status-icon">
|
||||
<div className='hbox'>
|
||||
<span className='test-file-test-status-icon'>
|
||||
{statusIcon(test.outcome)}
|
||||
</span>
|
||||
<span>
|
||||
|
|
|
|||
|
|
@ -44,11 +44,11 @@ export const TestFilesView: React.FC<{
|
|||
}, [report, filter]);
|
||||
return <>
|
||||
<div className='mt-2 mx-1' style={{ display: 'flex' }}>
|
||||
{projectNames.length === 1 && !!projectNames[0] && <div data-testid="project-name" style={{ color: 'var(--color-fg-subtle)' }}>Project: {projectNames[0]}</div>}
|
||||
{!filter.empty() && <div data-testid="filtered-tests-count" style={{ color: 'var(--color-fg-subtle)', padding: '0 10px' }}>Filtered: {filteredStats.total} {!!filteredStats.total && ('(' + msToString(filteredStats.duration) + ')')}</div>}
|
||||
{projectNames.length === 1 && !!projectNames[0] && <div data-testid='project-name' style={{ color: 'var(--color-fg-subtle)' }}>Project: {projectNames[0]}</div>}
|
||||
{!filter.empty() && <div data-testid='filtered-tests-count' style={{ color: 'var(--color-fg-subtle)', padding: '0 10px' }}>Filtered: {filteredStats.total} {!!filteredStats.total && ('(' + msToString(filteredStats.duration) + ')')}</div>}
|
||||
<div style={{ flex: 'auto' }}></div>
|
||||
<div data-testid="overall-time" style={{ color: 'var(--color-fg-subtle)', marginRight: '10px' }}>{report ? new Date(report.startTime).toLocaleString() : ''}</div>
|
||||
<div data-testid="overall-duration" style={{ color: 'var(--color-fg-subtle)' }}>Total time: {msToString(report?.duration ?? 0)}</div>
|
||||
<div data-testid='overall-time' style={{ color: 'var(--color-fg-subtle)', marginRight: '10px' }}>{report ? new Date(report.startTime).toLocaleString() : ''}</div>
|
||||
<div data-testid='overall-duration' style={{ color: 'var(--color-fg-subtle)' }}>Total time: {msToString(report?.duration ?? 0)}</div>
|
||||
</div>
|
||||
{report && !!report.errors.length && <AutoChip header='Errors' dataTestId='report-errors'>
|
||||
{report.errors.map((error, index) => <TestErrorView key={'test-report-error-message-' + index} error={error}></TestErrorView>)}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
# See src/server/injected/README.md.
|
||||
lib/**/injected/
|
||||
# Include all binaries that we ship with the package.
|
||||
!bin/*
|
||||
!bin/**/*
|
||||
# Include FFMPEG
|
||||
!third_party/ffmpeg/*
|
||||
# Include generated types and entrypoint.
|
||||
|
|
|
|||
|
|
@ -3,15 +3,15 @@
|
|||
"browsers": [
|
||||
{
|
||||
"name": "chromium",
|
||||
"revision": "1127",
|
||||
"revision": "1128",
|
||||
"installByDefault": true,
|
||||
"browserVersion": "127.0.6533.57"
|
||||
"browserVersion": "128.0.6613.7"
|
||||
},
|
||||
{
|
||||
"name": "chromium-tip-of-tree",
|
||||
"revision": "1243",
|
||||
"revision": "1244",
|
||||
"installByDefault": false,
|
||||
"browserVersion": "128.0.6613.0"
|
||||
"browserVersion": "129.0.6616.0"
|
||||
},
|
||||
{
|
||||
"name": "firefox",
|
||||
|
|
@ -37,7 +37,7 @@
|
|||
"mac12": "2009",
|
||||
"mac12-arm64": "2009"
|
||||
},
|
||||
"browserVersion": "17.4"
|
||||
"browserVersion": "18.0"
|
||||
},
|
||||
{
|
||||
"name": "ffmpeg",
|
||||
|
|
|
|||
|
|
@ -151,8 +151,14 @@ export class BrowserType extends ChannelOwner<channels.BrowserTypeChannel> imple
|
|||
page._onClose();
|
||||
context._onClose();
|
||||
}
|
||||
browser?._didClose();
|
||||
connection.close(reason || closeError);
|
||||
// Give a chance to any API call promises to reject upon page/context closure.
|
||||
// This happens naturally when we receive page.onClose and browser.onClose from the server
|
||||
// in separate tasks. However, upon pipe closure we used to dispatch them all synchronously
|
||||
// here and promises did not have a chance to reject.
|
||||
// The order of rejects vs closure is a part of the API contract and our test runner
|
||||
// relies on it to attribute rejections to the right test.
|
||||
setTimeout(() => browser?._didClose(), 0);
|
||||
};
|
||||
pipe.on('closed', params => onPipeClosed(params.reason));
|
||||
connection.onmessage = message => this._wrapApiCall(() => pipe.send({ message }).catch(() => onPipeClosed()), /* isInternal */ true);
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ export module Protocol {
|
|||
- from 'checked' to 'selected': states which apply to widgets
|
||||
- from 'activedescendant' to 'owns' - relationships between elements other than parent/child/sibling.
|
||||
*/
|
||||
export type AXPropertyName = "busy"|"disabled"|"editable"|"focusable"|"focused"|"hidden"|"hiddenRoot"|"invalid"|"keyshortcuts"|"settable"|"roledescription"|"live"|"atomic"|"relevant"|"root"|"autocomplete"|"hasPopup"|"level"|"multiselectable"|"orientation"|"multiline"|"readonly"|"required"|"valuemin"|"valuemax"|"valuetext"|"checked"|"expanded"|"modal"|"pressed"|"selected"|"activedescendant"|"controls"|"describedby"|"details"|"errormessage"|"flowto"|"labelledby"|"owns";
|
||||
export type AXPropertyName = "busy"|"disabled"|"editable"|"focusable"|"focused"|"hidden"|"hiddenRoot"|"invalid"|"keyshortcuts"|"settable"|"roledescription"|"live"|"atomic"|"relevant"|"root"|"autocomplete"|"hasPopup"|"level"|"multiselectable"|"orientation"|"multiline"|"readonly"|"required"|"valuemin"|"valuemax"|"valuetext"|"checked"|"expanded"|"modal"|"pressed"|"selected"|"activedescendant"|"controls"|"describedby"|"details"|"errormessage"|"flowto"|"labelledby"|"owns"|"url";
|
||||
/**
|
||||
* A node in the accessibility tree.
|
||||
*/
|
||||
|
|
@ -875,7 +875,7 @@ instead of "limited-quirks".
|
|||
sharedDictionaryError: SharedDictionaryError;
|
||||
request: AffectedRequest;
|
||||
}
|
||||
export type GenericIssueErrorType = "CrossOriginPortalPostMessageError"|"FormLabelForNameError"|"FormDuplicateIdForInputError"|"FormInputWithNoLabelError"|"FormAutocompleteAttributeEmptyError"|"FormEmptyIdAndNameAttributesForInputError"|"FormAriaLabelledByToNonExistingId"|"FormInputAssignedAutocompleteValueToIdOrNameAttributeError"|"FormLabelHasNeitherForNorNestedInput"|"FormLabelForMatchesNonExistingIdError"|"FormInputHasWrongButWellIntendedAutocompleteValueError"|"ResponseWasBlockedByORB";
|
||||
export type GenericIssueErrorType = "FormLabelForNameError"|"FormDuplicateIdForInputError"|"FormInputWithNoLabelError"|"FormAutocompleteAttributeEmptyError"|"FormEmptyIdAndNameAttributesForInputError"|"FormAriaLabelledByToNonExistingId"|"FormInputAssignedAutocompleteValueToIdOrNameAttributeError"|"FormLabelHasNeitherForNorNestedInput"|"FormLabelForMatchesNonExistingIdError"|"FormInputHasWrongButWellIntendedAutocompleteValueError"|"ResponseWasBlockedByORB";
|
||||
/**
|
||||
* Depending on the concrete errorType, different properties are set.
|
||||
*/
|
||||
|
|
@ -934,7 +934,7 @@ Should be updated alongside RequestIdTokenStatus in
|
|||
third_party/blink/public/mojom/devtools/inspector_issue.mojom to include
|
||||
all cases except for success.
|
||||
*/
|
||||
export type FederatedAuthRequestIssueReason = "ShouldEmbargo"|"TooManyRequests"|"WellKnownHttpNotFound"|"WellKnownNoResponse"|"WellKnownInvalidResponse"|"WellKnownListEmpty"|"WellKnownInvalidContentType"|"ConfigNotInWellKnown"|"WellKnownTooBig"|"ConfigHttpNotFound"|"ConfigNoResponse"|"ConfigInvalidResponse"|"ConfigInvalidContentType"|"ClientMetadataHttpNotFound"|"ClientMetadataNoResponse"|"ClientMetadataInvalidResponse"|"ClientMetadataInvalidContentType"|"DisabledInSettings"|"ErrorFetchingSignin"|"InvalidSigninResponse"|"AccountsHttpNotFound"|"AccountsNoResponse"|"AccountsInvalidResponse"|"AccountsListEmpty"|"AccountsInvalidContentType"|"IdTokenHttpNotFound"|"IdTokenNoResponse"|"IdTokenInvalidResponse"|"IdTokenIdpErrorResponse"|"IdTokenCrossSiteIdpErrorResponse"|"IdTokenInvalidRequest"|"IdTokenInvalidContentType"|"ErrorIdToken"|"Canceled"|"RpPageNotVisible"|"SilentMediationFailure"|"ThirdPartyCookiesBlocked"|"NotSignedInWithIdp"|"MissingTransientUserActivation"|"ReplacedByButtonMode"|"RelyingPartyOriginIsOpaque"|"TypeNotMatching";
|
||||
export type FederatedAuthRequestIssueReason = "ShouldEmbargo"|"TooManyRequests"|"WellKnownHttpNotFound"|"WellKnownNoResponse"|"WellKnownInvalidResponse"|"WellKnownListEmpty"|"WellKnownInvalidContentType"|"ConfigNotInWellKnown"|"WellKnownTooBig"|"ConfigHttpNotFound"|"ConfigNoResponse"|"ConfigInvalidResponse"|"ConfigInvalidContentType"|"ClientMetadataHttpNotFound"|"ClientMetadataNoResponse"|"ClientMetadataInvalidResponse"|"ClientMetadataInvalidContentType"|"IdpNotPotentiallyTrustworthy"|"DisabledInSettings"|"DisabledInFlags"|"ErrorFetchingSignin"|"InvalidSigninResponse"|"AccountsHttpNotFound"|"AccountsNoResponse"|"AccountsInvalidResponse"|"AccountsListEmpty"|"AccountsInvalidContentType"|"IdTokenHttpNotFound"|"IdTokenNoResponse"|"IdTokenInvalidResponse"|"IdTokenIdpErrorResponse"|"IdTokenCrossSiteIdpErrorResponse"|"IdTokenInvalidRequest"|"IdTokenInvalidContentType"|"ErrorIdToken"|"Canceled"|"RpPageNotVisible"|"SilentMediationFailure"|"ThirdPartyCookiesBlocked"|"NotSignedInWithIdp"|"MissingTransientUserActivation"|"ReplacedByButtonMode"|"InvalidFieldsSpecified"|"RelyingPartyOriginIsOpaque"|"TypeNotMatching";
|
||||
export interface FederatedAuthUserInfoRequestIssueDetails {
|
||||
federatedAuthUserInfoRequestIssueReason: FederatedAuthUserInfoRequestIssueReason;
|
||||
}
|
||||
|
|
@ -1480,6 +1480,10 @@ Note that userVisibleOnly = true is the only currently supported type.
|
|||
* For "clipboard" permission, may specify allowWithoutSanitization.
|
||||
*/
|
||||
allowWithoutSanitization?: boolean;
|
||||
/**
|
||||
* For "fullscreen" permission, must specify allowWithoutGesture:true.
|
||||
*/
|
||||
allowWithoutGesture?: boolean;
|
||||
/**
|
||||
* For "camera" permission, may specify panTiltZoom.
|
||||
*/
|
||||
|
|
@ -2559,6 +2563,7 @@ stylesheet rules) this rule came from.
|
|||
* Associated style declaration.
|
||||
*/
|
||||
style: CSSStyle;
|
||||
active: boolean;
|
||||
}
|
||||
/**
|
||||
* CSS keyframes rule representation.
|
||||
|
|
@ -2888,9 +2893,14 @@ attributes) for a DOM node identified by `nodeId`.
|
|||
*/
|
||||
cssPositionFallbackRules?: CSSPositionFallbackRule[];
|
||||
/**
|
||||
* A list of CSS @position-try rules matching this node, based on the position-try-options property.
|
||||
* A list of CSS @position-try rules matching this node, based on the position-try-fallbacks property.
|
||||
*/
|
||||
cssPositionTryRules?: CSSPositionTryRule[];
|
||||
/**
|
||||
* Index of the active fallback in the applied position-try-fallback property,
|
||||
will not be set if there is no active position-try fallback.
|
||||
*/
|
||||
activePositionFallbackIndex?: number;
|
||||
/**
|
||||
* A list of CSS at-property rules matching this node.
|
||||
*/
|
||||
|
|
@ -5907,6 +5917,11 @@ See https://w3c.github.io/sensors/#automation for more information.
|
|||
xyz?: SensorReadingXYZ;
|
||||
quaternion?: SensorReadingQuaternion;
|
||||
}
|
||||
export type PressureSource = "cpu";
|
||||
export type PressureState = "nominal"|"fair"|"serious"|"critical";
|
||||
export interface PressureMetadata {
|
||||
available?: boolean;
|
||||
}
|
||||
/**
|
||||
* Enum of image types that can be disabled.
|
||||
*/
|
||||
|
|
@ -6190,6 +6205,30 @@ by setSensorOverrideEnabled.
|
|||
}
|
||||
export type setSensorOverrideReadingsReturnValue = {
|
||||
}
|
||||
/**
|
||||
* Overrides a pressure source of a given type, as used by the Compute
|
||||
Pressure API, so that updates to PressureObserver.observe() are provided
|
||||
via setPressureStateOverride instead of being retrieved from
|
||||
platform-provided telemetry data.
|
||||
*/
|
||||
export type setPressureSourceOverrideEnabledParameters = {
|
||||
enabled: boolean;
|
||||
source: PressureSource;
|
||||
metadata?: PressureMetadata;
|
||||
}
|
||||
export type setPressureSourceOverrideEnabledReturnValue = {
|
||||
}
|
||||
/**
|
||||
* Provides a given pressure state that will be processed and eventually be
|
||||
delivered to PressureObserver users. |source| must have been previously
|
||||
overridden by setPressureSourceOverrideEnabled.
|
||||
*/
|
||||
export type setPressureStateOverrideParameters = {
|
||||
source: PressureSource;
|
||||
state: PressureState;
|
||||
}
|
||||
export type setPressureStateOverrideReturnValue = {
|
||||
}
|
||||
/**
|
||||
* Overrides the Idle state.
|
||||
*/
|
||||
|
|
@ -6533,6 +6572,54 @@ following the last read). Some types of streams may only support sequential read
|
|||
}
|
||||
}
|
||||
|
||||
export module FileSystem {
|
||||
export interface File {
|
||||
name: string;
|
||||
/**
|
||||
* Timestamp
|
||||
*/
|
||||
lastModified: Network.TimeSinceEpoch;
|
||||
/**
|
||||
* Size in bytes
|
||||
*/
|
||||
size: number;
|
||||
type: string;
|
||||
}
|
||||
export interface Directory {
|
||||
name: string;
|
||||
nestedDirectories: string[];
|
||||
/**
|
||||
* Files that are directly nested under this directory.
|
||||
*/
|
||||
nestedFiles: File[];
|
||||
}
|
||||
export interface BucketFileSystemLocator {
|
||||
/**
|
||||
* Storage key
|
||||
*/
|
||||
storageKey: Storage.SerializedStorageKey;
|
||||
/**
|
||||
* Bucket name. Not passing a `bucketName` will retrieve the default Bucket. (https://developer.mozilla.org/en-US/docs/Web/API/Storage_API#storage_buckets)
|
||||
*/
|
||||
bucketName?: string;
|
||||
/**
|
||||
* Path to the directory using each path component as an array item.
|
||||
*/
|
||||
pathComponents: string[];
|
||||
}
|
||||
|
||||
|
||||
export type getDirectoryParameters = {
|
||||
bucketFileSystemLocator: BucketFileSystemLocator;
|
||||
}
|
||||
export type getDirectoryReturnValue = {
|
||||
/**
|
||||
* Returns the directory object at the path.
|
||||
*/
|
||||
directory: Directory;
|
||||
}
|
||||
}
|
||||
|
||||
export module IndexedDB {
|
||||
/**
|
||||
* Database with an array of object stores.
|
||||
|
|
@ -9048,7 +9135,7 @@ the same request (but not for redirected requests).
|
|||
initiatorIPAddressSpace: IPAddressSpace;
|
||||
privateNetworkRequestPolicy: PrivateNetworkRequestPolicy;
|
||||
}
|
||||
export type CrossOriginOpenerPolicyValue = "SameOrigin"|"SameOriginAllowPopups"|"RestrictProperties"|"UnsafeNone"|"SameOriginPlusCoep"|"RestrictPropertiesPlusCoep";
|
||||
export type CrossOriginOpenerPolicyValue = "SameOrigin"|"SameOriginAllowPopups"|"RestrictProperties"|"UnsafeNone"|"SameOriginPlusCoep"|"RestrictPropertiesPlusCoep"|"NoopenerAllowPopups";
|
||||
export interface CrossOriginOpenerPolicyStatus {
|
||||
value: CrossOriginOpenerPolicyValue;
|
||||
reportOnlyValue: CrossOriginOpenerPolicyValue;
|
||||
|
|
@ -9731,6 +9818,10 @@ preemptively (e.g. a cache hit).
|
|||
*/
|
||||
issuedTokenCount?: number;
|
||||
}
|
||||
/**
|
||||
* Fired once security policy has been updated.
|
||||
*/
|
||||
export type policyUpdatedPayload = void;
|
||||
/**
|
||||
* Fired once when parsing the .wbn file has succeeded.
|
||||
The event contains the information about the web bundle contents.
|
||||
|
|
@ -11278,7 +11369,7 @@ as an ad.
|
|||
* All Permissions Policy features. This enum should match the one defined
|
||||
in third_party/blink/renderer/core/permissions_policy/permissions_policy_features.json5.
|
||||
*/
|
||||
export type PermissionsPolicyFeature = "accelerometer"|"ambient-light-sensor"|"attribution-reporting"|"autoplay"|"bluetooth"|"browsing-topics"|"camera"|"captured-surface-control"|"ch-dpr"|"ch-device-memory"|"ch-downlink"|"ch-ect"|"ch-prefers-color-scheme"|"ch-prefers-reduced-motion"|"ch-prefers-reduced-transparency"|"ch-rtt"|"ch-save-data"|"ch-ua"|"ch-ua-arch"|"ch-ua-bitness"|"ch-ua-platform"|"ch-ua-model"|"ch-ua-mobile"|"ch-ua-form-factors"|"ch-ua-full-version"|"ch-ua-full-version-list"|"ch-ua-platform-version"|"ch-ua-wow64"|"ch-viewport-height"|"ch-viewport-width"|"ch-width"|"clipboard-read"|"clipboard-write"|"compute-pressure"|"cross-origin-isolated"|"deferred-fetch"|"direct-sockets"|"display-capture"|"document-domain"|"encrypted-media"|"execution-while-out-of-viewport"|"execution-while-not-rendered"|"focus-without-user-activation"|"fullscreen"|"frobulate"|"gamepad"|"geolocation"|"gyroscope"|"hid"|"identity-credentials-get"|"idle-detection"|"interest-cohort"|"join-ad-interest-group"|"keyboard-map"|"local-fonts"|"magnetometer"|"microphone"|"midi"|"otp-credentials"|"payment"|"picture-in-picture"|"private-aggregation"|"private-state-token-issuance"|"private-state-token-redemption"|"publickey-credentials-create"|"publickey-credentials-get"|"run-ad-auction"|"screen-wake-lock"|"serial"|"shared-autofill"|"shared-storage"|"shared-storage-select-url"|"smart-card"|"speaker-selection"|"storage-access"|"sub-apps"|"sync-xhr"|"unload"|"usb"|"usb-unrestricted"|"vertical-scroll"|"web-printing"|"web-share"|"window-management"|"xr-spatial-tracking";
|
||||
export type PermissionsPolicyFeature = "accelerometer"|"ambient-light-sensor"|"attribution-reporting"|"autoplay"|"bluetooth"|"browsing-topics"|"camera"|"captured-surface-control"|"ch-dpr"|"ch-device-memory"|"ch-downlink"|"ch-ect"|"ch-prefers-color-scheme"|"ch-prefers-reduced-motion"|"ch-prefers-reduced-transparency"|"ch-rtt"|"ch-save-data"|"ch-ua"|"ch-ua-arch"|"ch-ua-bitness"|"ch-ua-platform"|"ch-ua-model"|"ch-ua-mobile"|"ch-ua-form-factors"|"ch-ua-full-version"|"ch-ua-full-version-list"|"ch-ua-platform-version"|"ch-ua-wow64"|"ch-viewport-height"|"ch-viewport-width"|"ch-width"|"clipboard-read"|"clipboard-write"|"compute-pressure"|"cross-origin-isolated"|"deferred-fetch"|"digital-credentials-get"|"direct-sockets"|"display-capture"|"document-domain"|"encrypted-media"|"execution-while-out-of-viewport"|"execution-while-not-rendered"|"focus-without-user-activation"|"fullscreen"|"frobulate"|"gamepad"|"geolocation"|"gyroscope"|"hid"|"identity-credentials-get"|"idle-detection"|"interest-cohort"|"join-ad-interest-group"|"keyboard-map"|"local-fonts"|"magnetometer"|"microphone"|"midi"|"otp-credentials"|"payment"|"picture-in-picture"|"private-aggregation"|"private-state-token-issuance"|"private-state-token-redemption"|"publickey-credentials-create"|"publickey-credentials-get"|"run-ad-auction"|"screen-wake-lock"|"serial"|"shared-autofill"|"shared-storage"|"shared-storage-select-url"|"smart-card"|"speaker-selection"|"storage-access"|"sub-apps"|"sync-xhr"|"unload"|"usb"|"usb-unrestricted"|"vertical-scroll"|"web-printing"|"web-share"|"window-management"|"xr-spatial-tracking";
|
||||
/**
|
||||
* Reason for a permissions policy feature to be disabled.
|
||||
*/
|
||||
|
|
@ -11866,7 +11957,7 @@ https://github.com/WICG/manifest-incubations/blob/gh-pages/scope_extensions-expl
|
|||
/**
|
||||
* List of not restored reasons for back-forward cache.
|
||||
*/
|
||||
export type BackForwardCacheNotRestoredReason = "NotPrimaryMainFrame"|"BackForwardCacheDisabled"|"RelatedActiveContentsExist"|"HTTPStatusNotOK"|"SchemeNotHTTPOrHTTPS"|"Loading"|"WasGrantedMediaAccess"|"DisableForRenderFrameHostCalled"|"DomainNotAllowed"|"HTTPMethodNotGET"|"SubframeIsNavigating"|"Timeout"|"CacheLimit"|"JavaScriptExecution"|"RendererProcessKilled"|"RendererProcessCrashed"|"SchedulerTrackedFeatureUsed"|"ConflictingBrowsingInstance"|"CacheFlushed"|"ServiceWorkerVersionActivation"|"SessionRestored"|"ServiceWorkerPostMessage"|"EnteredBackForwardCacheBeforeServiceWorkerHostAdded"|"RenderFrameHostReused_SameSite"|"RenderFrameHostReused_CrossSite"|"ServiceWorkerClaim"|"IgnoreEventAndEvict"|"HaveInnerContents"|"TimeoutPuttingInCache"|"BackForwardCacheDisabledByLowMemory"|"BackForwardCacheDisabledByCommandLine"|"NetworkRequestDatapipeDrainedAsBytesConsumer"|"NetworkRequestRedirected"|"NetworkRequestTimeout"|"NetworkExceedsBufferLimit"|"NavigationCancelledWhileRestoring"|"NotMostRecentNavigationEntry"|"BackForwardCacheDisabledForPrerender"|"UserAgentOverrideDiffers"|"ForegroundCacheLimit"|"BrowsingInstanceNotSwapped"|"BackForwardCacheDisabledForDelegate"|"UnloadHandlerExistsInMainFrame"|"UnloadHandlerExistsInSubFrame"|"ServiceWorkerUnregistration"|"CacheControlNoStore"|"CacheControlNoStoreCookieModified"|"CacheControlNoStoreHTTPOnlyCookieModified"|"NoResponseHead"|"Unknown"|"ActivationNavigationsDisallowedForBug1234857"|"ErrorDocument"|"FencedFramesEmbedder"|"CookieDisabled"|"HTTPAuthRequired"|"CookieFlushed"|"BroadcastChannelOnMessage"|"WebViewSettingsChanged"|"WebViewJavaScriptObjectChanged"|"WebViewMessageListenerInjected"|"WebViewSafeBrowsingAllowlistChanged"|"WebViewDocumentStartJavascriptChanged"|"WebSocket"|"WebTransport"|"WebRTC"|"MainResourceHasCacheControlNoStore"|"MainResourceHasCacheControlNoCache"|"SubresourceHasCacheControlNoStore"|"SubresourceHasCacheControlNoCache"|"ContainsPlugins"|"DocumentLoaded"|"OutstandingNetworkRequestOthers"|"RequestedMIDIPermission"|"RequestedAudioCapturePermission"|"RequestedVideoCapturePermission"|"RequestedBackForwardCacheBlockedSensors"|"RequestedBackgroundWorkPermission"|"BroadcastChannel"|"WebXR"|"SharedWorker"|"WebLocks"|"WebHID"|"WebShare"|"RequestedStorageAccessGrant"|"WebNfc"|"OutstandingNetworkRequestFetch"|"OutstandingNetworkRequestXHR"|"AppBanner"|"Printing"|"WebDatabase"|"PictureInPicture"|"Portal"|"SpeechRecognizer"|"IdleManager"|"PaymentManager"|"SpeechSynthesis"|"KeyboardLock"|"WebOTPService"|"OutstandingNetworkRequestDirectSocket"|"InjectedJavascript"|"InjectedStyleSheet"|"KeepaliveRequest"|"IndexedDBEvent"|"Dummy"|"JsNetworkRequestReceivedCacheControlNoStoreResource"|"WebRTCSticky"|"WebTransportSticky"|"WebSocketSticky"|"SmartCard"|"LiveMediaStreamTrack"|"UnloadHandler"|"ParserAborted"|"ContentSecurityHandler"|"ContentWebAuthenticationAPI"|"ContentFileChooser"|"ContentSerial"|"ContentFileSystemAccess"|"ContentMediaDevicesDispatcherHost"|"ContentWebBluetooth"|"ContentWebUSB"|"ContentMediaSessionService"|"ContentScreenReader"|"EmbedderPopupBlockerTabHelper"|"EmbedderSafeBrowsingTriggeredPopupBlocker"|"EmbedderSafeBrowsingThreatDetails"|"EmbedderAppBannerManager"|"EmbedderDomDistillerViewerSource"|"EmbedderDomDistillerSelfDeletingRequestDelegate"|"EmbedderOomInterventionTabHelper"|"EmbedderOfflinePage"|"EmbedderChromePasswordManagerClientBindCredentialManager"|"EmbedderPermissionRequestManager"|"EmbedderModalDialog"|"EmbedderExtensions"|"EmbedderExtensionMessaging"|"EmbedderExtensionMessagingForOpenPort"|"EmbedderExtensionSentMessageToCachedFrame"|"RequestedByWebViewClient";
|
||||
export type BackForwardCacheNotRestoredReason = "NotPrimaryMainFrame"|"BackForwardCacheDisabled"|"RelatedActiveContentsExist"|"HTTPStatusNotOK"|"SchemeNotHTTPOrHTTPS"|"Loading"|"WasGrantedMediaAccess"|"DisableForRenderFrameHostCalled"|"DomainNotAllowed"|"HTTPMethodNotGET"|"SubframeIsNavigating"|"Timeout"|"CacheLimit"|"JavaScriptExecution"|"RendererProcessKilled"|"RendererProcessCrashed"|"SchedulerTrackedFeatureUsed"|"ConflictingBrowsingInstance"|"CacheFlushed"|"ServiceWorkerVersionActivation"|"SessionRestored"|"ServiceWorkerPostMessage"|"EnteredBackForwardCacheBeforeServiceWorkerHostAdded"|"RenderFrameHostReused_SameSite"|"RenderFrameHostReused_CrossSite"|"ServiceWorkerClaim"|"IgnoreEventAndEvict"|"HaveInnerContents"|"TimeoutPuttingInCache"|"BackForwardCacheDisabledByLowMemory"|"BackForwardCacheDisabledByCommandLine"|"NetworkRequestDatapipeDrainedAsBytesConsumer"|"NetworkRequestRedirected"|"NetworkRequestTimeout"|"NetworkExceedsBufferLimit"|"NavigationCancelledWhileRestoring"|"NotMostRecentNavigationEntry"|"BackForwardCacheDisabledForPrerender"|"UserAgentOverrideDiffers"|"ForegroundCacheLimit"|"BrowsingInstanceNotSwapped"|"BackForwardCacheDisabledForDelegate"|"UnloadHandlerExistsInMainFrame"|"UnloadHandlerExistsInSubFrame"|"ServiceWorkerUnregistration"|"CacheControlNoStore"|"CacheControlNoStoreCookieModified"|"CacheControlNoStoreHTTPOnlyCookieModified"|"NoResponseHead"|"Unknown"|"ActivationNavigationsDisallowedForBug1234857"|"ErrorDocument"|"FencedFramesEmbedder"|"CookieDisabled"|"HTTPAuthRequired"|"CookieFlushed"|"BroadcastChannelOnMessage"|"WebViewSettingsChanged"|"WebViewJavaScriptObjectChanged"|"WebViewMessageListenerInjected"|"WebViewSafeBrowsingAllowlistChanged"|"WebViewDocumentStartJavascriptChanged"|"WebSocket"|"WebTransport"|"WebRTC"|"MainResourceHasCacheControlNoStore"|"MainResourceHasCacheControlNoCache"|"SubresourceHasCacheControlNoStore"|"SubresourceHasCacheControlNoCache"|"ContainsPlugins"|"DocumentLoaded"|"OutstandingNetworkRequestOthers"|"RequestedMIDIPermission"|"RequestedAudioCapturePermission"|"RequestedVideoCapturePermission"|"RequestedBackForwardCacheBlockedSensors"|"RequestedBackgroundWorkPermission"|"BroadcastChannel"|"WebXR"|"SharedWorker"|"WebLocks"|"WebHID"|"WebShare"|"RequestedStorageAccessGrant"|"WebNfc"|"OutstandingNetworkRequestFetch"|"OutstandingNetworkRequestXHR"|"AppBanner"|"Printing"|"WebDatabase"|"PictureInPicture"|"SpeechRecognizer"|"IdleManager"|"PaymentManager"|"SpeechSynthesis"|"KeyboardLock"|"WebOTPService"|"OutstandingNetworkRequestDirectSocket"|"InjectedJavascript"|"InjectedStyleSheet"|"KeepaliveRequest"|"IndexedDBEvent"|"Dummy"|"JsNetworkRequestReceivedCacheControlNoStoreResource"|"WebRTCSticky"|"WebTransportSticky"|"WebSocketSticky"|"SmartCard"|"LiveMediaStreamTrack"|"UnloadHandler"|"ParserAborted"|"ContentSecurityHandler"|"ContentWebAuthenticationAPI"|"ContentFileChooser"|"ContentSerial"|"ContentFileSystemAccess"|"ContentMediaDevicesDispatcherHost"|"ContentWebBluetooth"|"ContentWebUSB"|"ContentMediaSessionService"|"ContentScreenReader"|"EmbedderPopupBlockerTabHelper"|"EmbedderSafeBrowsingTriggeredPopupBlocker"|"EmbedderSafeBrowsingThreatDetails"|"EmbedderAppBannerManager"|"EmbedderDomDistillerViewerSource"|"EmbedderDomDistillerSelfDeletingRequestDelegate"|"EmbedderOomInterventionTabHelper"|"EmbedderOfflinePage"|"EmbedderChromePasswordManagerClientBindCredentialManager"|"EmbedderPermissionRequestManager"|"EmbedderModalDialog"|"EmbedderExtensions"|"EmbedderExtensionMessaging"|"EmbedderExtensionMessagingForOpenPort"|"EmbedderExtensionSentMessageToCachedFrame"|"RequestedByWebViewClient";
|
||||
/**
|
||||
* Types of not restored reasons for back-forward cache.
|
||||
*/
|
||||
|
|
@ -14053,6 +14144,25 @@ int
|
|||
eventReportWindows: AttributionReportingEventReportWindows;
|
||||
}
|
||||
export type AttributionReportingTriggerDataMatching = "exact"|"modulus";
|
||||
export interface AttributionReportingAggregatableDebugReportingData {
|
||||
keyPiece: UnsignedInt128AsBase16;
|
||||
/**
|
||||
* number instead of integer because not all uint32 can be represented by
|
||||
int
|
||||
*/
|
||||
value: number;
|
||||
types: string[];
|
||||
}
|
||||
export interface AttributionReportingAggregatableDebugReportingConfig {
|
||||
/**
|
||||
* number instead of integer because not all uint32 can be represented by
|
||||
int, only present for source registrations
|
||||
*/
|
||||
budget?: number;
|
||||
keyPiece: UnsignedInt128AsBase16;
|
||||
debugData: AttributionReportingAggregatableDebugReportingData[];
|
||||
aggregationCoordinatorOrigin?: string;
|
||||
}
|
||||
export interface AttributionReportingSourceRegistration {
|
||||
time: Network.TimeSinceEpoch;
|
||||
/**
|
||||
|
|
@ -14074,8 +14184,10 @@ int
|
|||
aggregationKeys: AttributionReportingAggregationKeysEntry[];
|
||||
debugKey?: UnsignedInt64AsBase10;
|
||||
triggerDataMatching: AttributionReportingTriggerDataMatching;
|
||||
destinationLimitPriority: SignedInt64AsBase10;
|
||||
aggregatableDebugReportingConfig: AttributionReportingAggregatableDebugReportingConfig;
|
||||
}
|
||||
export type AttributionReportingSourceRegistrationResult = "success"|"internalError"|"insufficientSourceCapacity"|"insufficientUniqueDestinationCapacity"|"excessiveReportingOrigins"|"prohibitedByBrowserPolicy"|"successNoised"|"destinationReportingLimitReached"|"destinationGlobalLimitReached"|"destinationBothLimitsReached"|"reportingOriginsPerSiteLimitReached"|"exceedsMaxChannelCapacity"|"exceedsMaxTriggerStateCardinality";
|
||||
export type AttributionReportingSourceRegistrationResult = "success"|"internalError"|"insufficientSourceCapacity"|"insufficientUniqueDestinationCapacity"|"excessiveReportingOrigins"|"prohibitedByBrowserPolicy"|"successNoised"|"destinationReportingLimitReached"|"destinationGlobalLimitReached"|"destinationBothLimitsReached"|"reportingOriginsPerSiteLimitReached"|"exceedsMaxChannelCapacity"|"exceedsMaxTriggerStateCardinality"|"destinationPerDayReportingLimitReached";
|
||||
export type AttributionReportingSourceRegistrationTimeConfig = "include"|"exclude";
|
||||
export interface AttributionReportingAggregatableValueDictEntry {
|
||||
key: string;
|
||||
|
|
@ -14084,6 +14196,7 @@ int
|
|||
int
|
||||
*/
|
||||
value: number;
|
||||
filteringId: UnsignedInt64AsBase10;
|
||||
}
|
||||
export interface AttributionReportingAggregatableValueEntry {
|
||||
values: AttributionReportingAggregatableValueDictEntry[];
|
||||
|
|
@ -14111,10 +14224,12 @@ int
|
|||
eventTriggerData: AttributionReportingEventTriggerData[];
|
||||
aggregatableTriggerData: AttributionReportingAggregatableTriggerData[];
|
||||
aggregatableValues: AttributionReportingAggregatableValueEntry[];
|
||||
aggregatableFilteringIdMaxBytes: number;
|
||||
debugReporting: boolean;
|
||||
aggregationCoordinatorOrigin?: string;
|
||||
sourceRegistrationTimeConfig: AttributionReportingSourceRegistrationTimeConfig;
|
||||
triggerContextId?: string;
|
||||
aggregatableDebugReportingConfig: AttributionReportingAggregatableDebugReportingConfig;
|
||||
}
|
||||
export type AttributionReportingEventLevelResult = "success"|"successDroppedLowerPriority"|"internalError"|"noCapacityForAttributionDestination"|"noMatchingSources"|"deduplicated"|"excessiveAttributions"|"priorityTooLow"|"neverAttributedSource"|"excessiveReportingOrigins"|"noMatchingSourceFilterData"|"prohibitedByBrowserPolicy"|"noMatchingConfigurations"|"excessiveReports"|"falselyAttributedSource"|"reportWindowPassed"|"notRegistered"|"reportWindowNotStarted"|"noMatchingTriggerData";
|
||||
export type AttributionReportingAggregatableResult = "success"|"internalError"|"noCapacityForAttributionDestination"|"noMatchingSources"|"excessiveAttributions"|"excessiveReportingOrigins"|"noHistograms"|"insufficientBudget"|"noMatchingSourceFilterData"|"notRegistered"|"prohibitedByBrowserPolicy"|"deduplicated"|"reportWindowPassed"|"excessiveReports";
|
||||
|
|
@ -14980,7 +15095,7 @@ supported.
|
|||
browserContextId?: Browser.BrowserContextID;
|
||||
/**
|
||||
* Provides additional details for specific target types. For example, for
|
||||
the type of "page", this may be set to "portal" or "prerender".
|
||||
the type of "page", this may be set to "prerender".
|
||||
*/
|
||||
subtype?: string;
|
||||
}
|
||||
|
|
@ -16807,7 +16922,7 @@ possible for multiple rule sets and links to trigger a single attempt.
|
|||
/**
|
||||
* List of FinalStatus reasons for Prerender2.
|
||||
*/
|
||||
export type PrerenderFinalStatus = "Activated"|"Destroyed"|"LowEndDevice"|"InvalidSchemeRedirect"|"InvalidSchemeNavigation"|"NavigationRequestBlockedByCsp"|"MainFrameNavigation"|"MojoBinderPolicy"|"RendererProcessCrashed"|"RendererProcessKilled"|"Download"|"TriggerDestroyed"|"NavigationNotCommitted"|"NavigationBadHttpStatus"|"ClientCertRequested"|"NavigationRequestNetworkError"|"CancelAllHostsForTesting"|"DidFailLoad"|"Stop"|"SslCertificateError"|"LoginAuthRequested"|"UaChangeRequiresReload"|"BlockedByClient"|"AudioOutputDeviceRequested"|"MixedContent"|"TriggerBackgrounded"|"MemoryLimitExceeded"|"DataSaverEnabled"|"TriggerUrlHasEffectiveUrl"|"ActivatedBeforeStarted"|"InactivePageRestriction"|"StartFailed"|"TimeoutBackgrounded"|"CrossSiteRedirectInInitialNavigation"|"CrossSiteNavigationInInitialNavigation"|"SameSiteCrossOriginRedirectNotOptInInInitialNavigation"|"SameSiteCrossOriginNavigationNotOptInInInitialNavigation"|"ActivationNavigationParameterMismatch"|"ActivatedInBackground"|"EmbedderHostDisallowed"|"ActivationNavigationDestroyedBeforeSuccess"|"TabClosedByUserGesture"|"TabClosedWithoutUserGesture"|"PrimaryMainFrameRendererProcessCrashed"|"PrimaryMainFrameRendererProcessKilled"|"ActivationFramePolicyNotCompatible"|"PreloadingDisabled"|"BatterySaverEnabled"|"ActivatedDuringMainFrameNavigation"|"PreloadingUnsupportedByWebContents"|"CrossSiteRedirectInMainFrameNavigation"|"CrossSiteNavigationInMainFrameNavigation"|"SameSiteCrossOriginRedirectNotOptInInMainFrameNavigation"|"SameSiteCrossOriginNavigationNotOptInInMainFrameNavigation"|"MemoryPressureOnTrigger"|"MemoryPressureAfterTriggered"|"PrerenderingDisabledByDevTools"|"SpeculationRuleRemoved"|"ActivatedWithAuxiliaryBrowsingContexts"|"MaxNumOfRunningEagerPrerendersExceeded"|"MaxNumOfRunningNonEagerPrerendersExceeded"|"MaxNumOfRunningEmbedderPrerendersExceeded"|"PrerenderingUrlHasEffectiveUrl"|"RedirectedPrerenderingUrlHasEffectiveUrl"|"ActivationUrlHasEffectiveUrl"|"JavaScriptInterfaceAdded"|"JavaScriptInterfaceRemoved"|"AllPrerenderingCanceled";
|
||||
export type PrerenderFinalStatus = "Activated"|"Destroyed"|"LowEndDevice"|"InvalidSchemeRedirect"|"InvalidSchemeNavigation"|"NavigationRequestBlockedByCsp"|"MainFrameNavigation"|"MojoBinderPolicy"|"RendererProcessCrashed"|"RendererProcessKilled"|"Download"|"TriggerDestroyed"|"NavigationNotCommitted"|"NavigationBadHttpStatus"|"ClientCertRequested"|"NavigationRequestNetworkError"|"CancelAllHostsForTesting"|"DidFailLoad"|"Stop"|"SslCertificateError"|"LoginAuthRequested"|"UaChangeRequiresReload"|"BlockedByClient"|"AudioOutputDeviceRequested"|"MixedContent"|"TriggerBackgrounded"|"MemoryLimitExceeded"|"DataSaverEnabled"|"TriggerUrlHasEffectiveUrl"|"ActivatedBeforeStarted"|"InactivePageRestriction"|"StartFailed"|"TimeoutBackgrounded"|"CrossSiteRedirectInInitialNavigation"|"CrossSiteNavigationInInitialNavigation"|"SameSiteCrossOriginRedirectNotOptInInInitialNavigation"|"SameSiteCrossOriginNavigationNotOptInInInitialNavigation"|"ActivationNavigationParameterMismatch"|"ActivatedInBackground"|"EmbedderHostDisallowed"|"ActivationNavigationDestroyedBeforeSuccess"|"TabClosedByUserGesture"|"TabClosedWithoutUserGesture"|"PrimaryMainFrameRendererProcessCrashed"|"PrimaryMainFrameRendererProcessKilled"|"ActivationFramePolicyNotCompatible"|"PreloadingDisabled"|"BatterySaverEnabled"|"ActivatedDuringMainFrameNavigation"|"PreloadingUnsupportedByWebContents"|"CrossSiteRedirectInMainFrameNavigation"|"CrossSiteNavigationInMainFrameNavigation"|"SameSiteCrossOriginRedirectNotOptInInMainFrameNavigation"|"SameSiteCrossOriginNavigationNotOptInInMainFrameNavigation"|"MemoryPressureOnTrigger"|"MemoryPressureAfterTriggered"|"PrerenderingDisabledByDevTools"|"SpeculationRuleRemoved"|"ActivatedWithAuxiliaryBrowsingContexts"|"MaxNumOfRunningEagerPrerendersExceeded"|"MaxNumOfRunningNonEagerPrerendersExceeded"|"MaxNumOfRunningEmbedderPrerendersExceeded"|"PrerenderingUrlHasEffectiveUrl"|"RedirectedPrerenderingUrlHasEffectiveUrl"|"ActivationUrlHasEffectiveUrl"|"JavaScriptInterfaceAdded"|"JavaScriptInterfaceRemoved"|"AllPrerenderingCanceled"|"WindowClosed";
|
||||
/**
|
||||
* Preloading status values, see also PreloadingTriggeringOutcome. This
|
||||
status is shared by prefetchStatusUpdated and prerenderStatusUpdated.
|
||||
|
|
@ -17021,6 +17136,10 @@ https://www.iana.org/assignments/media-types/media-types.xhtml
|
|||
accepts: FileHandlerAccept[];
|
||||
displayName: string;
|
||||
}
|
||||
/**
|
||||
* If user prefers opening the app in browser or an app window.
|
||||
*/
|
||||
export type DisplayMode = "standalone"|"browser";
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -17061,7 +17180,7 @@ manifestId.
|
|||
export type installReturnValue = {
|
||||
}
|
||||
/**
|
||||
* Uninstals the given manifest_id and closes any opened app windows.
|
||||
* Uninstalls the given manifest_id and closes any opened app windows.
|
||||
*/
|
||||
export type uninstallParameters = {
|
||||
manifestId: string;
|
||||
|
|
@ -17090,7 +17209,7 @@ the files. The API returns one or more page Target.TargetIDs which can be
|
|||
used to attach to via Target.attachToTarget or similar APIs.
|
||||
If some files in the parameters cannot be handled by the web app, they will
|
||||
be ignored. If none of the files can be handled, this API returns an error.
|
||||
If no files provided as the parameter, this API also returns an error.
|
||||
If no files are provided as the parameter, this API also returns an error.
|
||||
|
||||
According to the definition of the file handlers in the manifest file, one
|
||||
Target.TargetID may represent a page handling one or more files. The order
|
||||
|
|
@ -17111,13 +17230,44 @@ TODO(crbug.com/339454034): Check the existences of the input files.
|
|||
/**
|
||||
* Opens the current page in its web app identified by the manifest id, needs
|
||||
to be called on a page target. This function returns immediately without
|
||||
waiting for the app finishing loading.
|
||||
waiting for the app to finish loading.
|
||||
*/
|
||||
export type openCurrentPageInAppParameters = {
|
||||
manifestId: string;
|
||||
}
|
||||
export type openCurrentPageInAppReturnValue = {
|
||||
}
|
||||
/**
|
||||
* Changes user settings of the web app identified by its manifestId. If the
|
||||
app was not installed, this command returns an error. Unset parameters will
|
||||
be ignored; unrecognized values will cause an error.
|
||||
|
||||
Unlike the ones defined in the manifest files of the web apps, these
|
||||
settings are provided by the browser and controlled by the users, they
|
||||
impact the way the browser handling the web apps.
|
||||
|
||||
See the comment of each parameter.
|
||||
*/
|
||||
export type changeAppUserSettingsParameters = {
|
||||
manifestId: string;
|
||||
/**
|
||||
* If user allows the links clicked on by the user in the app's scope, or
|
||||
extended scope if the manifest has scope extensions and the flags
|
||||
`DesktopPWAsLinkCapturingWithScopeExtensions` and
|
||||
`WebAppEnableScopeExtensions` are enabled.
|
||||
|
||||
Note, the API does not support resetting the linkCapturing to the
|
||||
initial value, uninstalling and installing the web app again will reset
|
||||
it.
|
||||
|
||||
TODO(crbug.com/339453269): Setting this value on ChromeOS is not
|
||||
supported yet.
|
||||
*/
|
||||
linkCapturing?: boolean;
|
||||
displayMode?: DisplayMode;
|
||||
}
|
||||
export type changeAppUserSettingsReturnValue = {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -19824,6 +19974,7 @@ Error was thrown.
|
|||
"Network.responseReceivedExtraInfo": Network.responseReceivedExtraInfoPayload;
|
||||
"Network.responseReceivedEarlyHints": Network.responseReceivedEarlyHintsPayload;
|
||||
"Network.trustTokenOperationDone": Network.trustTokenOperationDonePayload;
|
||||
"Network.policyUpdated": Network.policyUpdatedPayload;
|
||||
"Network.subresourceWebBundleMetadataReceived": Network.subresourceWebBundleMetadataReceivedPayload;
|
||||
"Network.subresourceWebBundleMetadataError": Network.subresourceWebBundleMetadataErrorPayload;
|
||||
"Network.subresourceWebBundleInnerResponseParsed": Network.subresourceWebBundleInnerResponseParsedPayload;
|
||||
|
|
@ -20139,6 +20290,8 @@ Error was thrown.
|
|||
"Emulation.getOverriddenSensorInformation": Emulation.getOverriddenSensorInformationParameters;
|
||||
"Emulation.setSensorOverrideEnabled": Emulation.setSensorOverrideEnabledParameters;
|
||||
"Emulation.setSensorOverrideReadings": Emulation.setSensorOverrideReadingsParameters;
|
||||
"Emulation.setPressureSourceOverrideEnabled": Emulation.setPressureSourceOverrideEnabledParameters;
|
||||
"Emulation.setPressureStateOverride": Emulation.setPressureStateOverrideParameters;
|
||||
"Emulation.setIdleOverride": Emulation.setIdleOverrideParameters;
|
||||
"Emulation.clearIdleOverride": Emulation.clearIdleOverrideParameters;
|
||||
"Emulation.setNavigatorOverrides": Emulation.setNavigatorOverridesParameters;
|
||||
|
|
@ -20159,6 +20312,7 @@ Error was thrown.
|
|||
"IO.close": IO.closeParameters;
|
||||
"IO.read": IO.readParameters;
|
||||
"IO.resolveBlob": IO.resolveBlobParameters;
|
||||
"FileSystem.getDirectory": FileSystem.getDirectoryParameters;
|
||||
"IndexedDB.clearObjectStore": IndexedDB.clearObjectStoreParameters;
|
||||
"IndexedDB.deleteDatabase": IndexedDB.deleteDatabaseParameters;
|
||||
"IndexedDB.deleteObjectStoreEntries": IndexedDB.deleteObjectStoreEntriesParameters;
|
||||
|
|
@ -20461,6 +20615,7 @@ Error was thrown.
|
|||
"PWA.launch": PWA.launchParameters;
|
||||
"PWA.launchFilesInApp": PWA.launchFilesInAppParameters;
|
||||
"PWA.openCurrentPageInApp": PWA.openCurrentPageInAppParameters;
|
||||
"PWA.changeAppUserSettings": PWA.changeAppUserSettingsParameters;
|
||||
"Console.clearMessages": Console.clearMessagesParameters;
|
||||
"Console.disable": Console.disableParameters;
|
||||
"Console.enable": Console.enableParameters;
|
||||
|
|
@ -20735,6 +20890,8 @@ Error was thrown.
|
|||
"Emulation.getOverriddenSensorInformation": Emulation.getOverriddenSensorInformationReturnValue;
|
||||
"Emulation.setSensorOverrideEnabled": Emulation.setSensorOverrideEnabledReturnValue;
|
||||
"Emulation.setSensorOverrideReadings": Emulation.setSensorOverrideReadingsReturnValue;
|
||||
"Emulation.setPressureSourceOverrideEnabled": Emulation.setPressureSourceOverrideEnabledReturnValue;
|
||||
"Emulation.setPressureStateOverride": Emulation.setPressureStateOverrideReturnValue;
|
||||
"Emulation.setIdleOverride": Emulation.setIdleOverrideReturnValue;
|
||||
"Emulation.clearIdleOverride": Emulation.clearIdleOverrideReturnValue;
|
||||
"Emulation.setNavigatorOverrides": Emulation.setNavigatorOverridesReturnValue;
|
||||
|
|
@ -20755,6 +20912,7 @@ Error was thrown.
|
|||
"IO.close": IO.closeReturnValue;
|
||||
"IO.read": IO.readReturnValue;
|
||||
"IO.resolveBlob": IO.resolveBlobReturnValue;
|
||||
"FileSystem.getDirectory": FileSystem.getDirectoryReturnValue;
|
||||
"IndexedDB.clearObjectStore": IndexedDB.clearObjectStoreReturnValue;
|
||||
"IndexedDB.deleteDatabase": IndexedDB.deleteDatabaseReturnValue;
|
||||
"IndexedDB.deleteObjectStoreEntries": IndexedDB.deleteObjectStoreEntriesReturnValue;
|
||||
|
|
@ -21057,6 +21215,7 @@ Error was thrown.
|
|||
"PWA.launch": PWA.launchReturnValue;
|
||||
"PWA.launchFilesInApp": PWA.launchFilesInAppReturnValue;
|
||||
"PWA.openCurrentPageInApp": PWA.openCurrentPageInAppReturnValue;
|
||||
"PWA.changeAppUserSettings": PWA.changeAppUserSettingsReturnValue;
|
||||
"Console.clearMessages": Console.clearMessagesReturnValue;
|
||||
"Console.disable": Console.disableReturnValue;
|
||||
"Console.enable": Console.enableReturnValue;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"Blackberry PlayBook": {
|
||||
"userAgent": "Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML like Gecko) Version/17.4 Safari/536.2+",
|
||||
"userAgent": "Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML like Gecko) Version/18.0 Safari/536.2+",
|
||||
"viewport": {
|
||||
"width": 600,
|
||||
"height": 1024
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"Blackberry PlayBook landscape": {
|
||||
"userAgent": "Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML like Gecko) Version/17.4 Safari/536.2+",
|
||||
"userAgent": "Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML like Gecko) Version/18.0 Safari/536.2+",
|
||||
"viewport": {
|
||||
"width": 1024,
|
||||
"height": 600
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"BlackBerry Z30": {
|
||||
"userAgent": "Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/17.4 Mobile Safari/537.10+",
|
||||
"userAgent": "Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/18.0 Mobile Safari/537.10+",
|
||||
"viewport": {
|
||||
"width": 360,
|
||||
"height": 640
|
||||
|
|
@ -33,7 +33,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"BlackBerry Z30 landscape": {
|
||||
"userAgent": "Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/17.4 Mobile Safari/537.10+",
|
||||
"userAgent": "Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/18.0 Mobile Safari/537.10+",
|
||||
"viewport": {
|
||||
"width": 640,
|
||||
"height": 360
|
||||
|
|
@ -44,7 +44,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"Galaxy Note 3": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.3; en-us; SM-N900T Build/JSS15J) AppleWebKit/534.30 (KHTML, like Gecko) Version/17.4 Mobile Safari/534.30",
|
||||
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.3; en-us; SM-N900T Build/JSS15J) AppleWebKit/534.30 (KHTML, like Gecko) Version/18.0 Mobile Safari/534.30",
|
||||
"viewport": {
|
||||
"width": 360,
|
||||
"height": 640
|
||||
|
|
@ -55,7 +55,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"Galaxy Note 3 landscape": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.3; en-us; SM-N900T Build/JSS15J) AppleWebKit/534.30 (KHTML, like Gecko) Version/17.4 Mobile Safari/534.30",
|
||||
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.3; en-us; SM-N900T Build/JSS15J) AppleWebKit/534.30 (KHTML, like Gecko) Version/18.0 Mobile Safari/534.30",
|
||||
"viewport": {
|
||||
"width": 640,
|
||||
"height": 360
|
||||
|
|
@ -66,7 +66,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"Galaxy Note II": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.1; en-us; GT-N7100 Build/JRO03C) AppleWebKit/534.30 (KHTML, like Gecko) Version/17.4 Mobile Safari/534.30",
|
||||
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.1; en-us; GT-N7100 Build/JRO03C) AppleWebKit/534.30 (KHTML, like Gecko) Version/18.0 Mobile Safari/534.30",
|
||||
"viewport": {
|
||||
"width": 360,
|
||||
"height": 640
|
||||
|
|
@ -77,7 +77,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"Galaxy Note II landscape": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.1; en-us; GT-N7100 Build/JRO03C) AppleWebKit/534.30 (KHTML, like Gecko) Version/17.4 Mobile Safari/534.30",
|
||||
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.1; en-us; GT-N7100 Build/JRO03C) AppleWebKit/534.30 (KHTML, like Gecko) Version/18.0 Mobile Safari/534.30",
|
||||
"viewport": {
|
||||
"width": 640,
|
||||
"height": 360
|
||||
|
|
@ -88,7 +88,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"Galaxy S III": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.0; en-us; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/17.4 Mobile Safari/534.30",
|
||||
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.0; en-us; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/18.0 Mobile Safari/534.30",
|
||||
"viewport": {
|
||||
"width": 360,
|
||||
"height": 640
|
||||
|
|
@ -99,7 +99,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"Galaxy S III landscape": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.0; en-us; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/17.4 Mobile Safari/534.30",
|
||||
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.0; en-us; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/18.0 Mobile Safari/534.30",
|
||||
"viewport": {
|
||||
"width": 640,
|
||||
"height": 360
|
||||
|
|
@ -110,7 +110,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"Galaxy S5": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 360,
|
||||
"height": 640
|
||||
|
|
@ -121,7 +121,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Galaxy S5 landscape": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 640,
|
||||
"height": 360
|
||||
|
|
@ -132,7 +132,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Galaxy S8": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 7.0; SM-G950U Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 7.0; SM-G950U Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 360,
|
||||
"height": 740
|
||||
|
|
@ -143,7 +143,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Galaxy S8 landscape": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 7.0; SM-G950U Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 7.0; SM-G950U Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 740,
|
||||
"height": 360
|
||||
|
|
@ -154,7 +154,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Galaxy S9+": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G965U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G965U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 320,
|
||||
"height": 658
|
||||
|
|
@ -165,7 +165,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Galaxy S9+ landscape": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G965U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G965U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 658,
|
||||
"height": 320
|
||||
|
|
@ -176,7 +176,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Galaxy Tab S4": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.1.0; SM-T837A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.1.0; SM-T837A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 712,
|
||||
"height": 1138
|
||||
|
|
@ -187,7 +187,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Galaxy Tab S4 landscape": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.1.0; SM-T837A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.1.0; SM-T837A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 1138,
|
||||
"height": 712
|
||||
|
|
@ -198,7 +198,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"iPad (gen 5)": {
|
||||
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"viewport": {
|
||||
"width": 768,
|
||||
"height": 1024
|
||||
|
|
@ -209,7 +209,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPad (gen 5) landscape": {
|
||||
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"viewport": {
|
||||
"width": 1024,
|
||||
"height": 768
|
||||
|
|
@ -220,7 +220,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPad (gen 6)": {
|
||||
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"viewport": {
|
||||
"width": 768,
|
||||
"height": 1024
|
||||
|
|
@ -231,7 +231,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPad (gen 6) landscape": {
|
||||
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"viewport": {
|
||||
"width": 1024,
|
||||
"height": 768
|
||||
|
|
@ -242,7 +242,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPad (gen 7)": {
|
||||
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"viewport": {
|
||||
"width": 810,
|
||||
"height": 1080
|
||||
|
|
@ -253,7 +253,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPad (gen 7) landscape": {
|
||||
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"viewport": {
|
||||
"width": 1080,
|
||||
"height": 810
|
||||
|
|
@ -264,7 +264,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPad Mini": {
|
||||
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"viewport": {
|
||||
"width": 768,
|
||||
"height": 1024
|
||||
|
|
@ -275,7 +275,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPad Mini landscape": {
|
||||
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"viewport": {
|
||||
"width": 1024,
|
||||
"height": 768
|
||||
|
|
@ -286,7 +286,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPad Pro 11": {
|
||||
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"viewport": {
|
||||
"width": 834,
|
||||
"height": 1194
|
||||
|
|
@ -297,7 +297,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPad Pro 11 landscape": {
|
||||
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"viewport": {
|
||||
"width": 1194,
|
||||
"height": 834
|
||||
|
|
@ -308,7 +308,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 6": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/17.4 Mobile/15A372 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/18.0 Mobile/15A372 Safari/604.1",
|
||||
"viewport": {
|
||||
"width": 375,
|
||||
"height": 667
|
||||
|
|
@ -319,7 +319,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 6 landscape": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/17.4 Mobile/15A372 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/18.0 Mobile/15A372 Safari/604.1",
|
||||
"viewport": {
|
||||
"width": 667,
|
||||
"height": 375
|
||||
|
|
@ -330,7 +330,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 6 Plus": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/17.4 Mobile/15A372 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/18.0 Mobile/15A372 Safari/604.1",
|
||||
"viewport": {
|
||||
"width": 414,
|
||||
"height": 736
|
||||
|
|
@ -341,7 +341,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 6 Plus landscape": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/17.4 Mobile/15A372 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/18.0 Mobile/15A372 Safari/604.1",
|
||||
"viewport": {
|
||||
"width": 736,
|
||||
"height": 414
|
||||
|
|
@ -352,7 +352,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 7": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/17.4 Mobile/15A372 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/18.0 Mobile/15A372 Safari/604.1",
|
||||
"viewport": {
|
||||
"width": 375,
|
||||
"height": 667
|
||||
|
|
@ -363,7 +363,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 7 landscape": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/17.4 Mobile/15A372 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/18.0 Mobile/15A372 Safari/604.1",
|
||||
"viewport": {
|
||||
"width": 667,
|
||||
"height": 375
|
||||
|
|
@ -374,7 +374,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 7 Plus": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/17.4 Mobile/15A372 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/18.0 Mobile/15A372 Safari/604.1",
|
||||
"viewport": {
|
||||
"width": 414,
|
||||
"height": 736
|
||||
|
|
@ -385,7 +385,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 7 Plus landscape": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/17.4 Mobile/15A372 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/18.0 Mobile/15A372 Safari/604.1",
|
||||
"viewport": {
|
||||
"width": 736,
|
||||
"height": 414
|
||||
|
|
@ -396,7 +396,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 8": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/17.4 Mobile/15A372 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/18.0 Mobile/15A372 Safari/604.1",
|
||||
"viewport": {
|
||||
"width": 375,
|
||||
"height": 667
|
||||
|
|
@ -407,7 +407,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 8 landscape": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/17.4 Mobile/15A372 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/18.0 Mobile/15A372 Safari/604.1",
|
||||
"viewport": {
|
||||
"width": 667,
|
||||
"height": 375
|
||||
|
|
@ -418,7 +418,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 8 Plus": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/17.4 Mobile/15A372 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/18.0 Mobile/15A372 Safari/604.1",
|
||||
"viewport": {
|
||||
"width": 414,
|
||||
"height": 736
|
||||
|
|
@ -429,7 +429,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 8 Plus landscape": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/17.4 Mobile/15A372 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/18.0 Mobile/15A372 Safari/604.1",
|
||||
"viewport": {
|
||||
"width": 736,
|
||||
"height": 414
|
||||
|
|
@ -440,7 +440,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone SE": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/17.4 Mobile/14E304 Safari/602.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/18.0 Mobile/14E304 Safari/602.1",
|
||||
"viewport": {
|
||||
"width": 320,
|
||||
"height": 568
|
||||
|
|
@ -451,7 +451,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone SE landscape": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/17.4 Mobile/14E304 Safari/602.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/18.0 Mobile/14E304 Safari/602.1",
|
||||
"viewport": {
|
||||
"width": 568,
|
||||
"height": 320
|
||||
|
|
@ -462,7 +462,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone X": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/17.4 Mobile/15A372 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/18.0 Mobile/15A372 Safari/604.1",
|
||||
"viewport": {
|
||||
"width": 375,
|
||||
"height": 812
|
||||
|
|
@ -473,7 +473,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone X landscape": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/17.4 Mobile/15A372 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/18.0 Mobile/15A372 Safari/604.1",
|
||||
"viewport": {
|
||||
"width": 812,
|
||||
"height": 375
|
||||
|
|
@ -484,7 +484,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone XR": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"viewport": {
|
||||
"width": 414,
|
||||
"height": 896
|
||||
|
|
@ -495,7 +495,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone XR landscape": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"viewport": {
|
||||
"width": 896,
|
||||
"height": 414
|
||||
|
|
@ -506,7 +506,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 11": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 414,
|
||||
"height": 896
|
||||
|
|
@ -521,7 +521,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 11 landscape": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 414,
|
||||
"height": 896
|
||||
|
|
@ -536,7 +536,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 11 Pro": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 375,
|
||||
"height": 812
|
||||
|
|
@ -551,7 +551,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 11 Pro landscape": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 375,
|
||||
"height": 812
|
||||
|
|
@ -566,7 +566,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 11 Pro Max": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 414,
|
||||
"height": 896
|
||||
|
|
@ -581,7 +581,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 11 Pro Max landscape": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 414,
|
||||
"height": 896
|
||||
|
|
@ -596,7 +596,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 12": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 390,
|
||||
"height": 844
|
||||
|
|
@ -611,7 +611,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 12 landscape": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 390,
|
||||
"height": 844
|
||||
|
|
@ -626,7 +626,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 12 Pro": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 390,
|
||||
"height": 844
|
||||
|
|
@ -641,7 +641,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 12 Pro landscape": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 390,
|
||||
"height": 844
|
||||
|
|
@ -656,7 +656,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 12 Pro Max": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 428,
|
||||
"height": 926
|
||||
|
|
@ -671,7 +671,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 12 Pro Max landscape": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 428,
|
||||
"height": 926
|
||||
|
|
@ -686,7 +686,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 12 Mini": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 375,
|
||||
"height": 812
|
||||
|
|
@ -701,7 +701,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 12 Mini landscape": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 375,
|
||||
"height": 812
|
||||
|
|
@ -716,7 +716,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 13": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 390,
|
||||
"height": 844
|
||||
|
|
@ -731,7 +731,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 13 landscape": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 390,
|
||||
"height": 844
|
||||
|
|
@ -746,7 +746,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 13 Pro": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 390,
|
||||
"height": 844
|
||||
|
|
@ -761,7 +761,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 13 Pro landscape": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 390,
|
||||
"height": 844
|
||||
|
|
@ -776,7 +776,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 13 Pro Max": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 428,
|
||||
"height": 926
|
||||
|
|
@ -791,7 +791,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 13 Pro Max landscape": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 428,
|
||||
"height": 926
|
||||
|
|
@ -806,7 +806,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 13 Mini": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 375,
|
||||
"height": 812
|
||||
|
|
@ -821,7 +821,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 13 Mini landscape": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 375,
|
||||
"height": 812
|
||||
|
|
@ -836,7 +836,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 14": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 390,
|
||||
"height": 844
|
||||
|
|
@ -851,7 +851,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 14 landscape": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 390,
|
||||
"height": 844
|
||||
|
|
@ -866,7 +866,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 14 Plus": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 428,
|
||||
"height": 926
|
||||
|
|
@ -881,7 +881,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 14 Plus landscape": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 428,
|
||||
"height": 926
|
||||
|
|
@ -896,7 +896,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 14 Pro": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 393,
|
||||
"height": 852
|
||||
|
|
@ -911,7 +911,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 14 Pro landscape": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 393,
|
||||
"height": 852
|
||||
|
|
@ -926,7 +926,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 14 Pro Max": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 430,
|
||||
"height": 932
|
||||
|
|
@ -941,7 +941,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 14 Pro Max landscape": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 430,
|
||||
"height": 932
|
||||
|
|
@ -956,7 +956,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 15": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 393,
|
||||
"height": 852
|
||||
|
|
@ -971,7 +971,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 15 landscape": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 393,
|
||||
"height": 852
|
||||
|
|
@ -986,7 +986,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 15 Plus": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 430,
|
||||
"height": 932
|
||||
|
|
@ -1001,7 +1001,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 15 Plus landscape": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 430,
|
||||
"height": 932
|
||||
|
|
@ -1016,7 +1016,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 15 Pro": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 393,
|
||||
"height": 852
|
||||
|
|
@ -1031,7 +1031,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 15 Pro landscape": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 393,
|
||||
"height": 852
|
||||
|
|
@ -1046,7 +1046,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 15 Pro Max": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 430,
|
||||
"height": 932
|
||||
|
|
@ -1061,7 +1061,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"iPhone 15 Pro Max landscape": {
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
||||
"screen": {
|
||||
"width": 430,
|
||||
"height": 932
|
||||
|
|
@ -1098,7 +1098,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"LG Optimus L70": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/127.0.6533.57 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/128.0.6613.7 Mobile Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 384,
|
||||
"height": 640
|
||||
|
|
@ -1109,7 +1109,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"LG Optimus L70 landscape": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/127.0.6533.57 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/128.0.6613.7 Mobile Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 640,
|
||||
"height": 384
|
||||
|
|
@ -1120,7 +1120,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Microsoft Lumia 550": {
|
||||
"userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 550) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36 Edge/14.14263",
|
||||
"userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 550) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36 Edge/14.14263",
|
||||
"viewport": {
|
||||
"width": 640,
|
||||
"height": 360
|
||||
|
|
@ -1131,7 +1131,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Microsoft Lumia 550 landscape": {
|
||||
"userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 550) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36 Edge/14.14263",
|
||||
"userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 550) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36 Edge/14.14263",
|
||||
"viewport": {
|
||||
"width": 360,
|
||||
"height": 640
|
||||
|
|
@ -1142,7 +1142,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Microsoft Lumia 950": {
|
||||
"userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36 Edge/14.14263",
|
||||
"userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36 Edge/14.14263",
|
||||
"viewport": {
|
||||
"width": 360,
|
||||
"height": 640
|
||||
|
|
@ -1153,7 +1153,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Microsoft Lumia 950 landscape": {
|
||||
"userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36 Edge/14.14263",
|
||||
"userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36 Edge/14.14263",
|
||||
"viewport": {
|
||||
"width": 640,
|
||||
"height": 360
|
||||
|
|
@ -1164,7 +1164,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Nexus 10": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 10 Build/MOB31T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 10 Build/MOB31T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 800,
|
||||
"height": 1280
|
||||
|
|
@ -1175,7 +1175,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Nexus 10 landscape": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 10 Build/MOB31T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 10 Build/MOB31T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 1280,
|
||||
"height": 800
|
||||
|
|
@ -1186,7 +1186,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Nexus 4": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 384,
|
||||
"height": 640
|
||||
|
|
@ -1197,7 +1197,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Nexus 4 landscape": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 640,
|
||||
"height": 384
|
||||
|
|
@ -1208,7 +1208,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Nexus 5": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 360,
|
||||
"height": 640
|
||||
|
|
@ -1219,7 +1219,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Nexus 5 landscape": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 640,
|
||||
"height": 360
|
||||
|
|
@ -1230,7 +1230,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Nexus 5X": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 5X Build/OPR4.170623.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 5X Build/OPR4.170623.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 412,
|
||||
"height": 732
|
||||
|
|
@ -1241,7 +1241,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Nexus 5X landscape": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 5X Build/OPR4.170623.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 5X Build/OPR4.170623.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 732,
|
||||
"height": 412
|
||||
|
|
@ -1252,7 +1252,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Nexus 6": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6 Build/N6F26U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6 Build/N6F26U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 412,
|
||||
"height": 732
|
||||
|
|
@ -1263,7 +1263,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Nexus 6 landscape": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6 Build/N6F26U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6 Build/N6F26U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 732,
|
||||
"height": 412
|
||||
|
|
@ -1274,7 +1274,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Nexus 6P": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 6P Build/OPP3.170518.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 6P Build/OPP3.170518.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 412,
|
||||
"height": 732
|
||||
|
|
@ -1285,7 +1285,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Nexus 6P landscape": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 6P Build/OPP3.170518.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 6P Build/OPP3.170518.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 732,
|
||||
"height": 412
|
||||
|
|
@ -1296,7 +1296,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Nexus 7": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 7 Build/MOB30X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 7 Build/MOB30X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 600,
|
||||
"height": 960
|
||||
|
|
@ -1307,7 +1307,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Nexus 7 landscape": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 7 Build/MOB30X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 7 Build/MOB30X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 960,
|
||||
"height": 600
|
||||
|
|
@ -1362,7 +1362,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"Pixel 2": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 411,
|
||||
"height": 731
|
||||
|
|
@ -1373,7 +1373,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Pixel 2 landscape": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 731,
|
||||
"height": 411
|
||||
|
|
@ -1384,7 +1384,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Pixel 2 XL": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Pixel 2 XL Build/OPD1.170816.004) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Pixel 2 XL Build/OPD1.170816.004) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 411,
|
||||
"height": 823
|
||||
|
|
@ -1395,7 +1395,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Pixel 2 XL landscape": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Pixel 2 XL Build/OPD1.170816.004) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Pixel 2 XL Build/OPD1.170816.004) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 823,
|
||||
"height": 411
|
||||
|
|
@ -1406,7 +1406,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Pixel 3": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 9; Pixel 3 Build/PQ1A.181105.017.A1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 9; Pixel 3 Build/PQ1A.181105.017.A1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 393,
|
||||
"height": 786
|
||||
|
|
@ -1417,7 +1417,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Pixel 3 landscape": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 9; Pixel 3 Build/PQ1A.181105.017.A1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 9; Pixel 3 Build/PQ1A.181105.017.A1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 786,
|
||||
"height": 393
|
||||
|
|
@ -1428,7 +1428,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Pixel 4": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 10; Pixel 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 10; Pixel 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 353,
|
||||
"height": 745
|
||||
|
|
@ -1439,7 +1439,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Pixel 4 landscape": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 10; Pixel 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 10; Pixel 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 745,
|
||||
"height": 353
|
||||
|
|
@ -1450,7 +1450,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Pixel 4a (5G)": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 4a (5G)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 4a (5G)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36",
|
||||
"screen": {
|
||||
"width": 412,
|
||||
"height": 892
|
||||
|
|
@ -1465,7 +1465,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Pixel 4a (5G) landscape": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 4a (5G)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 4a (5G)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36",
|
||||
"screen": {
|
||||
"height": 892,
|
||||
"width": 412
|
||||
|
|
@ -1480,7 +1480,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Pixel 5": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36",
|
||||
"screen": {
|
||||
"width": 393,
|
||||
"height": 851
|
||||
|
|
@ -1495,7 +1495,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Pixel 5 landscape": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36",
|
||||
"screen": {
|
||||
"width": 851,
|
||||
"height": 393
|
||||
|
|
@ -1510,7 +1510,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Pixel 7": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 14; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 14; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36",
|
||||
"screen": {
|
||||
"width": 412,
|
||||
"height": 915
|
||||
|
|
@ -1525,7 +1525,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Pixel 7 landscape": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 14; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 14; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36",
|
||||
"screen": {
|
||||
"width": 915,
|
||||
"height": 412
|
||||
|
|
@ -1540,7 +1540,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Moto G4": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 360,
|
||||
"height": 640
|
||||
|
|
@ -1551,7 +1551,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Moto G4 landscape": {
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Mobile Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 640,
|
||||
"height": 360
|
||||
|
|
@ -1562,7 +1562,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Desktop Chrome HiDPI": {
|
||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Safari/537.36",
|
||||
"screen": {
|
||||
"width": 1792,
|
||||
"height": 1120
|
||||
|
|
@ -1577,7 +1577,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Desktop Edge HiDPI": {
|
||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Safari/537.36 Edg/127.0.6533.57",
|
||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Safari/537.36 Edg/128.0.6613.7",
|
||||
"screen": {
|
||||
"width": 1792,
|
||||
"height": 1120
|
||||
|
|
@ -1607,7 +1607,7 @@
|
|||
"defaultBrowserType": "firefox"
|
||||
},
|
||||
"Desktop Safari": {
|
||||
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Safari/605.1.15",
|
||||
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Safari/605.1.15",
|
||||
"screen": {
|
||||
"width": 1792,
|
||||
"height": 1120
|
||||
|
|
@ -1622,7 +1622,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"Desktop Chrome": {
|
||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Safari/537.36",
|
||||
"screen": {
|
||||
"width": 1920,
|
||||
"height": 1080
|
||||
|
|
@ -1637,7 +1637,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"Desktop Edge": {
|
||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.57 Safari/537.36 Edg/127.0.6533.57",
|
||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.7 Safari/537.36 Edg/128.0.6613.7",
|
||||
"screen": {
|
||||
"width": 1920,
|
||||
"height": 1080
|
||||
|
|
|
|||
|
|
@ -230,6 +230,9 @@ class RecordActionTool implements RecorderTool {
|
|||
// So we check the hovered element instead, and if it is a range input, we skip click handling
|
||||
if (isRangeInput(this._hoveredElement))
|
||||
return;
|
||||
// Right clicks are handled by 'contextmenu' event if its auxclick
|
||||
if (event.button === 2 && event.type === 'auxclick')
|
||||
return;
|
||||
if (this._shouldIgnoreMouseEvent(event))
|
||||
return;
|
||||
if (this._actionInProgress(event))
|
||||
|
|
|
|||
|
|
@ -16,17 +16,28 @@
|
|||
|
||||
import net from 'net';
|
||||
import path from 'path';
|
||||
import http2 from 'http2';
|
||||
import type https from 'https';
|
||||
import fs from 'fs';
|
||||
import tls from 'tls';
|
||||
import stream from 'stream';
|
||||
import { createSocket } from '../utils/happy-eyeballs';
|
||||
import { globToRegex, isUnderTest, ManualPromise } from '../utils';
|
||||
import { createSocket, createTLSSocket } from '../utils/happy-eyeballs';
|
||||
import { isUnderTest, ManualPromise } from '../utils';
|
||||
import type { SocksSocketClosedPayload, SocksSocketDataPayload, SocksSocketRequestedPayload } from '../common/socksProxy';
|
||||
import { SocksProxy } from '../common/socksProxy';
|
||||
import type * as channels from '@protocol/channels';
|
||||
import { debugLogger } from '../utils/debugLogger';
|
||||
|
||||
let dummyServerTlsOptions: tls.TlsOptions | undefined = undefined;
|
||||
function loadDummyServerCertsIfNeeded() {
|
||||
if (dummyServerTlsOptions)
|
||||
return;
|
||||
dummyServerTlsOptions = {
|
||||
key: fs.readFileSync(path.join(__dirname, '../../bin/socks-certs/key.pem')),
|
||||
cert: fs.readFileSync(path.join(__dirname, '../../bin/socks-certs/cert.pem')),
|
||||
};
|
||||
}
|
||||
|
||||
class ALPNCache {
|
||||
private _cache = new Map<string, ManualPromise<string>>();
|
||||
|
||||
|
|
@ -42,22 +53,21 @@ class ALPNCache {
|
|||
const result = new ManualPromise<string>();
|
||||
this._cache.set(cacheKey, result);
|
||||
result.then(success);
|
||||
const socket = tls.connect({
|
||||
createTLSSocket({
|
||||
host,
|
||||
port,
|
||||
servername: net.isIP(host) ? undefined : host,
|
||||
ALPNProtocols: ['h2', 'http/1.1'],
|
||||
rejectUnauthorized: false,
|
||||
});
|
||||
socket.on('secureConnect', () => {
|
||||
// The server may not respond with ALPN, in which case we default to http/1.1.
|
||||
result.resolve(socket.alpnProtocol || 'http/1.1');
|
||||
socket.end();
|
||||
});
|
||||
socket.on('error', error => {
|
||||
}).then(socket => {
|
||||
socket.on('secureConnect', () => {
|
||||
// The server may not respond with ALPN, in which case we default to http/1.1.
|
||||
result.resolve(socket.alpnProtocol || 'http/1.1');
|
||||
socket.end();
|
||||
});
|
||||
}).catch(error => {
|
||||
debugLogger.log('client-certificates', `ALPN error: ${error.message}`);
|
||||
result.resolve('http/1.1');
|
||||
socket.end();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -71,17 +81,19 @@ class SocksProxyConnection {
|
|||
target!: net.Socket;
|
||||
// In case of http, we just pipe data to the target socket and they are |undefined|.
|
||||
internal: stream.Duplex | undefined;
|
||||
private _targetCloseEventListener: () => void;
|
||||
|
||||
constructor(socksProxy: ClientCertificatesProxy, uid: string, host: string, port: number) {
|
||||
this.socksProxy = socksProxy;
|
||||
this.uid = uid;
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
this._targetCloseEventListener = () => this.socksProxy._socksProxy.sendSocketEnd({ uid: this.uid });
|
||||
}
|
||||
|
||||
async connect() {
|
||||
this.target = await createSocket(rewriteToLocalhostIfNeeded(this.host), this.port);
|
||||
this.target.on('close', () => this.socksProxy._socksProxy.sendSocketEnd({ uid: this.uid }));
|
||||
this.target.on('close', this._targetCloseEventListener);
|
||||
this.target.on('error', error => this.socksProxy._socksProxy.sendSocketError({ uid: this.uid, error: error.message }));
|
||||
this.socksProxy._socksProxy.socketConnected({
|
||||
uid: this.uid,
|
||||
|
|
@ -123,15 +135,13 @@ class SocksProxyConnection {
|
|||
this.socksProxy.alpnCache.get(rewriteToLocalhostIfNeeded(this.host), this.port, alpnProtocolChosenByServer => {
|
||||
debugLogger.log('client-certificates', `Proxy->Target ${this.host}:${this.port} chooses ALPN ${alpnProtocolChosenByServer}`);
|
||||
const dummyServer = tls.createServer({
|
||||
key: fs.readFileSync(path.join(__dirname, '../../bin/socks-certs/key.pem')),
|
||||
cert: fs.readFileSync(path.join(__dirname, '../../bin/socks-certs/cert.pem')),
|
||||
...dummyServerTlsOptions,
|
||||
ALPNProtocols: alpnProtocolChosenByServer === 'h2' ? ['h2', 'http/1.1'] : ['http/1.1'],
|
||||
});
|
||||
this.internal?.on('close', () => dummyServer.close());
|
||||
dummyServer.emit('connection', this.internal);
|
||||
dummyServer.on('secureConnection', internalTLS => {
|
||||
debugLogger.log('client-certificates', `Browser->Proxy ${this.host}:${this.port} chooses ALPN ${internalTLS.alpnProtocol}`);
|
||||
internalTLS.on('close', () => this.socksProxy._socksProxy.sendSocketEnd({ uid: this.uid }));
|
||||
const tlsOptions: tls.ConnectionOptions = {
|
||||
socket: this.target,
|
||||
host: this.host,
|
||||
|
|
@ -146,8 +156,10 @@ class SocksProxyConnection {
|
|||
tlsOptions.ca = [fs.readFileSync(process.env.PWTEST_UNSUPPORTED_CUSTOM_CA)];
|
||||
const targetTLS = tls.connect(tlsOptions);
|
||||
|
||||
internalTLS.pipe(targetTLS);
|
||||
targetTLS.pipe(internalTLS);
|
||||
targetTLS.on('secureConnect', () => {
|
||||
internalTLS.pipe(targetTLS);
|
||||
targetTLS.pipe(internalTLS);
|
||||
});
|
||||
|
||||
// Handle close and errors
|
||||
const closeBothSockets = () => {
|
||||
|
|
@ -161,11 +173,30 @@ class SocksProxyConnection {
|
|||
internalTLS.on('error', () => closeBothSockets());
|
||||
targetTLS.on('error', error => {
|
||||
debugLogger.log('client-certificates', `error when connecting to target: ${error.message}`);
|
||||
const responseBody = 'Playwright client-certificate error: ' + error.message;
|
||||
if (internalTLS?.alpnProtocol === 'h2') {
|
||||
// https://github.com/nodejs/node/issues/46152
|
||||
// TODO: http2.performServerHandshake does not work here for some reason.
|
||||
// This method is available only in Node.js 20+
|
||||
if ('performServerHandshake' in http2) {
|
||||
// In case of an 'error' event on the target connection, we still need to perform the http2 handshake on the browser side.
|
||||
// This is an async operation, so we need to intercept the close event to prevent the socket from being closed too early.
|
||||
this.target.removeListener('close', this._targetCloseEventListener);
|
||||
// @ts-expect-error
|
||||
const session: http2.ServerHttp2Session = http2.performServerHandshake(internalTLS);
|
||||
session.on('stream', (stream: http2.ServerHttp2Stream) => {
|
||||
stream.respond({
|
||||
'content-type': 'text/html',
|
||||
[http2.constants.HTTP2_HEADER_STATUS]: 503,
|
||||
});
|
||||
stream.end(responseBody, () => {
|
||||
session.close();
|
||||
closeBothSockets();
|
||||
});
|
||||
stream.on('error', () => closeBothSockets());
|
||||
});
|
||||
} else {
|
||||
closeBothSockets();
|
||||
}
|
||||
} else {
|
||||
const responseBody = 'Playwright client-certificate error: ' + error.message;
|
||||
internalTLS.end([
|
||||
'HTTP/1.1 503 Internal Server Error',
|
||||
'Content-Type: text/html; charset=utf-8',
|
||||
|
|
@ -173,8 +204,8 @@ class SocksProxyConnection {
|
|||
'\r\n',
|
||||
responseBody,
|
||||
].join('\r\n'));
|
||||
closeBothSockets();
|
||||
}
|
||||
closeBothSockets();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -212,6 +243,7 @@ export class ClientCertificatesProxy {
|
|||
this._connections.get(payload.uid)?.onClose();
|
||||
this._connections.delete(payload.uid);
|
||||
});
|
||||
loadDummyServerCertsIfNeeded();
|
||||
}
|
||||
|
||||
public async listen(): Promise<string> {
|
||||
|
|
@ -224,20 +256,16 @@ export class ClientCertificatesProxy {
|
|||
}
|
||||
}
|
||||
|
||||
const kClientCertificatesGlobRegex = Symbol('kClientCertificatesGlobRegex');
|
||||
|
||||
export function clientCertificatesToTLSOptions(
|
||||
clientCertificates: channels.BrowserNewContextOptions['clientCertificates'],
|
||||
origin: string
|
||||
): Pick<https.RequestOptions, 'pfx' | 'key' | 'cert'> | undefined {
|
||||
const matchingCerts = clientCertificates?.filter(c => {
|
||||
let regex: RegExp | undefined = (c as any)[kClientCertificatesGlobRegex];
|
||||
if (!regex) {
|
||||
regex = globToRegex(c.origin);
|
||||
(c as any)[kClientCertificatesGlobRegex] = regex;
|
||||
try {
|
||||
return new URL(c.origin).origin === origin;
|
||||
} catch (error) {
|
||||
return c.origin === origin;
|
||||
}
|
||||
regex.lastIndex = 0;
|
||||
return regex.test(origin);
|
||||
});
|
||||
if (!matchingCerts || !matchingCerts.length)
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@ import { WKPage } from './wkPage';
|
|||
import { TargetClosedError } from '../errors';
|
||||
import type { SdkObject } from '../instrumentation';
|
||||
|
||||
const DEFAULT_USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Safari/605.1.15';
|
||||
const BROWSER_VERSION = '17.4';
|
||||
const DEFAULT_USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Safari/605.1.15';
|
||||
const BROWSER_VERSION = '18.0';
|
||||
|
||||
export class WKBrowser extends Browser {
|
||||
private readonly _connection: WKConnection;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import * as https from 'https';
|
|||
import * as net from 'net';
|
||||
import * as tls from 'tls';
|
||||
import { ManualPromise } from './manualPromise';
|
||||
import { assert } from './debug';
|
||||
|
||||
// Implementation(partial) of Happy Eyeballs 2 algorithm described in
|
||||
// https://www.rfc-editor.org/rfc/rfc8305
|
||||
|
|
@ -66,7 +67,41 @@ export async function createSocket(host: string, port: number): Promise<net.Sock
|
|||
});
|
||||
}
|
||||
|
||||
async function createConnectionAsync(options: http.ClientRequestArgs, oncreate: ((err: Error | null, socket?: net.Socket) => void) | undefined, useTLS: boolean) {
|
||||
export async function createTLSSocket(options: tls.ConnectionOptions): Promise<tls.TLSSocket> {
|
||||
return new Promise((resolve, reject) => {
|
||||
assert(options.host, 'host is required');
|
||||
if (net.isIP(options.host)) {
|
||||
const socket = tls.connect(options)
|
||||
socket.on('connect', () => resolve(socket));
|
||||
socket.on('error', error => reject(error));
|
||||
} else {
|
||||
createConnectionAsync(options, (err, socket) => {
|
||||
if (err)
|
||||
reject(err);
|
||||
if (socket)
|
||||
resolve(socket);
|
||||
}, true).catch(err => reject(err));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export async function createConnectionAsync(
|
||||
options: http.ClientRequestArgs,
|
||||
oncreate: ((err: Error | null, socket?: tls.TLSSocket) => void) | undefined,
|
||||
useTLS: true
|
||||
): Promise<void>;
|
||||
|
||||
export async function createConnectionAsync(
|
||||
options: http.ClientRequestArgs,
|
||||
oncreate: ((err: Error | null, socket?: net.Socket) => void) | undefined,
|
||||
useTLS: false
|
||||
): Promise<void>;
|
||||
|
||||
export async function createConnectionAsync(
|
||||
options: http.ClientRequestArgs,
|
||||
oncreate: ((err: Error | null, socket?: any) => void) | undefined,
|
||||
useTLS: boolean
|
||||
): Promise<void> {
|
||||
const lookup = (options as any).__testHookLookup || lookupAddresses;
|
||||
const hostname = clientRequestArgsToHostName(options);
|
||||
const addresses = await lookup(hostname);
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
import http from 'http';
|
||||
import https from 'https';
|
||||
import http2 from 'http2';
|
||||
import type net from 'net';
|
||||
import { getProxyForUrl } from '../utilsBundle';
|
||||
import { HttpsProxyAgent } from '../utilsBundle';
|
||||
|
|
@ -169,6 +170,14 @@ export function createHttpsServer(...args: any[]): https.Server {
|
|||
return server;
|
||||
}
|
||||
|
||||
export function createHttp2Server( onRequestHandler?: (request: http2.Http2ServerRequest, response: http2.Http2ServerResponse) => void,): http2.Http2SecureServer;
|
||||
export function createHttp2Server(options: http2.SecureServerOptions, onRequestHandler?: (request: http2.Http2ServerRequest, response: http2.Http2ServerResponse) => void,): http2.Http2SecureServer;
|
||||
export function createHttp2Server(...args: any[]): http2.Http2SecureServer {
|
||||
const server = http2.createSecureServer(...args);
|
||||
decorateServer(server);
|
||||
return server;
|
||||
}
|
||||
|
||||
export async function isURLAvailable(url: URL, ignoreHTTPSErrors: boolean, onLog?: (data: string) => void, onStdErr?: (data: string) => void) {
|
||||
let statusCode = await httpStatusCode(url, ignoreHTTPSErrors, onLog, onStdErr);
|
||||
if (statusCode === 404 && url.pathname === '/') {
|
||||
|
|
@ -200,7 +209,7 @@ async function httpStatusCode(url: URL, ignoreHTTPSErrors: boolean, onLog?: (dat
|
|||
});
|
||||
}
|
||||
|
||||
function decorateServer(server: http.Server | http.Server) {
|
||||
function decorateServer(server: net.Server) {
|
||||
const sockets = new Set<net.Socket>();
|
||||
server.on('connection', socket => {
|
||||
sockets.add(socket);
|
||||
|
|
|
|||
185
packages/playwright-core/types/protocol.d.ts
vendored
185
packages/playwright-core/types/protocol.d.ts
vendored
|
|
@ -112,7 +112,7 @@ export module Protocol {
|
|||
- from 'checked' to 'selected': states which apply to widgets
|
||||
- from 'activedescendant' to 'owns' - relationships between elements other than parent/child/sibling.
|
||||
*/
|
||||
export type AXPropertyName = "busy"|"disabled"|"editable"|"focusable"|"focused"|"hidden"|"hiddenRoot"|"invalid"|"keyshortcuts"|"settable"|"roledescription"|"live"|"atomic"|"relevant"|"root"|"autocomplete"|"hasPopup"|"level"|"multiselectable"|"orientation"|"multiline"|"readonly"|"required"|"valuemin"|"valuemax"|"valuetext"|"checked"|"expanded"|"modal"|"pressed"|"selected"|"activedescendant"|"controls"|"describedby"|"details"|"errormessage"|"flowto"|"labelledby"|"owns";
|
||||
export type AXPropertyName = "busy"|"disabled"|"editable"|"focusable"|"focused"|"hidden"|"hiddenRoot"|"invalid"|"keyshortcuts"|"settable"|"roledescription"|"live"|"atomic"|"relevant"|"root"|"autocomplete"|"hasPopup"|"level"|"multiselectable"|"orientation"|"multiline"|"readonly"|"required"|"valuemin"|"valuemax"|"valuetext"|"checked"|"expanded"|"modal"|"pressed"|"selected"|"activedescendant"|"controls"|"describedby"|"details"|"errormessage"|"flowto"|"labelledby"|"owns"|"url";
|
||||
/**
|
||||
* A node in the accessibility tree.
|
||||
*/
|
||||
|
|
@ -875,7 +875,7 @@ instead of "limited-quirks".
|
|||
sharedDictionaryError: SharedDictionaryError;
|
||||
request: AffectedRequest;
|
||||
}
|
||||
export type GenericIssueErrorType = "CrossOriginPortalPostMessageError"|"FormLabelForNameError"|"FormDuplicateIdForInputError"|"FormInputWithNoLabelError"|"FormAutocompleteAttributeEmptyError"|"FormEmptyIdAndNameAttributesForInputError"|"FormAriaLabelledByToNonExistingId"|"FormInputAssignedAutocompleteValueToIdOrNameAttributeError"|"FormLabelHasNeitherForNorNestedInput"|"FormLabelForMatchesNonExistingIdError"|"FormInputHasWrongButWellIntendedAutocompleteValueError"|"ResponseWasBlockedByORB";
|
||||
export type GenericIssueErrorType = "FormLabelForNameError"|"FormDuplicateIdForInputError"|"FormInputWithNoLabelError"|"FormAutocompleteAttributeEmptyError"|"FormEmptyIdAndNameAttributesForInputError"|"FormAriaLabelledByToNonExistingId"|"FormInputAssignedAutocompleteValueToIdOrNameAttributeError"|"FormLabelHasNeitherForNorNestedInput"|"FormLabelForMatchesNonExistingIdError"|"FormInputHasWrongButWellIntendedAutocompleteValueError"|"ResponseWasBlockedByORB";
|
||||
/**
|
||||
* Depending on the concrete errorType, different properties are set.
|
||||
*/
|
||||
|
|
@ -934,7 +934,7 @@ Should be updated alongside RequestIdTokenStatus in
|
|||
third_party/blink/public/mojom/devtools/inspector_issue.mojom to include
|
||||
all cases except for success.
|
||||
*/
|
||||
export type FederatedAuthRequestIssueReason = "ShouldEmbargo"|"TooManyRequests"|"WellKnownHttpNotFound"|"WellKnownNoResponse"|"WellKnownInvalidResponse"|"WellKnownListEmpty"|"WellKnownInvalidContentType"|"ConfigNotInWellKnown"|"WellKnownTooBig"|"ConfigHttpNotFound"|"ConfigNoResponse"|"ConfigInvalidResponse"|"ConfigInvalidContentType"|"ClientMetadataHttpNotFound"|"ClientMetadataNoResponse"|"ClientMetadataInvalidResponse"|"ClientMetadataInvalidContentType"|"DisabledInSettings"|"ErrorFetchingSignin"|"InvalidSigninResponse"|"AccountsHttpNotFound"|"AccountsNoResponse"|"AccountsInvalidResponse"|"AccountsListEmpty"|"AccountsInvalidContentType"|"IdTokenHttpNotFound"|"IdTokenNoResponse"|"IdTokenInvalidResponse"|"IdTokenIdpErrorResponse"|"IdTokenCrossSiteIdpErrorResponse"|"IdTokenInvalidRequest"|"IdTokenInvalidContentType"|"ErrorIdToken"|"Canceled"|"RpPageNotVisible"|"SilentMediationFailure"|"ThirdPartyCookiesBlocked"|"NotSignedInWithIdp"|"MissingTransientUserActivation"|"ReplacedByButtonMode"|"RelyingPartyOriginIsOpaque"|"TypeNotMatching";
|
||||
export type FederatedAuthRequestIssueReason = "ShouldEmbargo"|"TooManyRequests"|"WellKnownHttpNotFound"|"WellKnownNoResponse"|"WellKnownInvalidResponse"|"WellKnownListEmpty"|"WellKnownInvalidContentType"|"ConfigNotInWellKnown"|"WellKnownTooBig"|"ConfigHttpNotFound"|"ConfigNoResponse"|"ConfigInvalidResponse"|"ConfigInvalidContentType"|"ClientMetadataHttpNotFound"|"ClientMetadataNoResponse"|"ClientMetadataInvalidResponse"|"ClientMetadataInvalidContentType"|"IdpNotPotentiallyTrustworthy"|"DisabledInSettings"|"DisabledInFlags"|"ErrorFetchingSignin"|"InvalidSigninResponse"|"AccountsHttpNotFound"|"AccountsNoResponse"|"AccountsInvalidResponse"|"AccountsListEmpty"|"AccountsInvalidContentType"|"IdTokenHttpNotFound"|"IdTokenNoResponse"|"IdTokenInvalidResponse"|"IdTokenIdpErrorResponse"|"IdTokenCrossSiteIdpErrorResponse"|"IdTokenInvalidRequest"|"IdTokenInvalidContentType"|"ErrorIdToken"|"Canceled"|"RpPageNotVisible"|"SilentMediationFailure"|"ThirdPartyCookiesBlocked"|"NotSignedInWithIdp"|"MissingTransientUserActivation"|"ReplacedByButtonMode"|"InvalidFieldsSpecified"|"RelyingPartyOriginIsOpaque"|"TypeNotMatching";
|
||||
export interface FederatedAuthUserInfoRequestIssueDetails {
|
||||
federatedAuthUserInfoRequestIssueReason: FederatedAuthUserInfoRequestIssueReason;
|
||||
}
|
||||
|
|
@ -1480,6 +1480,10 @@ Note that userVisibleOnly = true is the only currently supported type.
|
|||
* For "clipboard" permission, may specify allowWithoutSanitization.
|
||||
*/
|
||||
allowWithoutSanitization?: boolean;
|
||||
/**
|
||||
* For "fullscreen" permission, must specify allowWithoutGesture:true.
|
||||
*/
|
||||
allowWithoutGesture?: boolean;
|
||||
/**
|
||||
* For "camera" permission, may specify panTiltZoom.
|
||||
*/
|
||||
|
|
@ -2559,6 +2563,7 @@ stylesheet rules) this rule came from.
|
|||
* Associated style declaration.
|
||||
*/
|
||||
style: CSSStyle;
|
||||
active: boolean;
|
||||
}
|
||||
/**
|
||||
* CSS keyframes rule representation.
|
||||
|
|
@ -2888,9 +2893,14 @@ attributes) for a DOM node identified by `nodeId`.
|
|||
*/
|
||||
cssPositionFallbackRules?: CSSPositionFallbackRule[];
|
||||
/**
|
||||
* A list of CSS @position-try rules matching this node, based on the position-try-options property.
|
||||
* A list of CSS @position-try rules matching this node, based on the position-try-fallbacks property.
|
||||
*/
|
||||
cssPositionTryRules?: CSSPositionTryRule[];
|
||||
/**
|
||||
* Index of the active fallback in the applied position-try-fallback property,
|
||||
will not be set if there is no active position-try fallback.
|
||||
*/
|
||||
activePositionFallbackIndex?: number;
|
||||
/**
|
||||
* A list of CSS at-property rules matching this node.
|
||||
*/
|
||||
|
|
@ -5907,6 +5917,11 @@ See https://w3c.github.io/sensors/#automation for more information.
|
|||
xyz?: SensorReadingXYZ;
|
||||
quaternion?: SensorReadingQuaternion;
|
||||
}
|
||||
export type PressureSource = "cpu";
|
||||
export type PressureState = "nominal"|"fair"|"serious"|"critical";
|
||||
export interface PressureMetadata {
|
||||
available?: boolean;
|
||||
}
|
||||
/**
|
||||
* Enum of image types that can be disabled.
|
||||
*/
|
||||
|
|
@ -6190,6 +6205,30 @@ by setSensorOverrideEnabled.
|
|||
}
|
||||
export type setSensorOverrideReadingsReturnValue = {
|
||||
}
|
||||
/**
|
||||
* Overrides a pressure source of a given type, as used by the Compute
|
||||
Pressure API, so that updates to PressureObserver.observe() are provided
|
||||
via setPressureStateOverride instead of being retrieved from
|
||||
platform-provided telemetry data.
|
||||
*/
|
||||
export type setPressureSourceOverrideEnabledParameters = {
|
||||
enabled: boolean;
|
||||
source: PressureSource;
|
||||
metadata?: PressureMetadata;
|
||||
}
|
||||
export type setPressureSourceOverrideEnabledReturnValue = {
|
||||
}
|
||||
/**
|
||||
* Provides a given pressure state that will be processed and eventually be
|
||||
delivered to PressureObserver users. |source| must have been previously
|
||||
overridden by setPressureSourceOverrideEnabled.
|
||||
*/
|
||||
export type setPressureStateOverrideParameters = {
|
||||
source: PressureSource;
|
||||
state: PressureState;
|
||||
}
|
||||
export type setPressureStateOverrideReturnValue = {
|
||||
}
|
||||
/**
|
||||
* Overrides the Idle state.
|
||||
*/
|
||||
|
|
@ -6533,6 +6572,54 @@ following the last read). Some types of streams may only support sequential read
|
|||
}
|
||||
}
|
||||
|
||||
export module FileSystem {
|
||||
export interface File {
|
||||
name: string;
|
||||
/**
|
||||
* Timestamp
|
||||
*/
|
||||
lastModified: Network.TimeSinceEpoch;
|
||||
/**
|
||||
* Size in bytes
|
||||
*/
|
||||
size: number;
|
||||
type: string;
|
||||
}
|
||||
export interface Directory {
|
||||
name: string;
|
||||
nestedDirectories: string[];
|
||||
/**
|
||||
* Files that are directly nested under this directory.
|
||||
*/
|
||||
nestedFiles: File[];
|
||||
}
|
||||
export interface BucketFileSystemLocator {
|
||||
/**
|
||||
* Storage key
|
||||
*/
|
||||
storageKey: Storage.SerializedStorageKey;
|
||||
/**
|
||||
* Bucket name. Not passing a `bucketName` will retrieve the default Bucket. (https://developer.mozilla.org/en-US/docs/Web/API/Storage_API#storage_buckets)
|
||||
*/
|
||||
bucketName?: string;
|
||||
/**
|
||||
* Path to the directory using each path component as an array item.
|
||||
*/
|
||||
pathComponents: string[];
|
||||
}
|
||||
|
||||
|
||||
export type getDirectoryParameters = {
|
||||
bucketFileSystemLocator: BucketFileSystemLocator;
|
||||
}
|
||||
export type getDirectoryReturnValue = {
|
||||
/**
|
||||
* Returns the directory object at the path.
|
||||
*/
|
||||
directory: Directory;
|
||||
}
|
||||
}
|
||||
|
||||
export module IndexedDB {
|
||||
/**
|
||||
* Database with an array of object stores.
|
||||
|
|
@ -9048,7 +9135,7 @@ the same request (but not for redirected requests).
|
|||
initiatorIPAddressSpace: IPAddressSpace;
|
||||
privateNetworkRequestPolicy: PrivateNetworkRequestPolicy;
|
||||
}
|
||||
export type CrossOriginOpenerPolicyValue = "SameOrigin"|"SameOriginAllowPopups"|"RestrictProperties"|"UnsafeNone"|"SameOriginPlusCoep"|"RestrictPropertiesPlusCoep";
|
||||
export type CrossOriginOpenerPolicyValue = "SameOrigin"|"SameOriginAllowPopups"|"RestrictProperties"|"UnsafeNone"|"SameOriginPlusCoep"|"RestrictPropertiesPlusCoep"|"NoopenerAllowPopups";
|
||||
export interface CrossOriginOpenerPolicyStatus {
|
||||
value: CrossOriginOpenerPolicyValue;
|
||||
reportOnlyValue: CrossOriginOpenerPolicyValue;
|
||||
|
|
@ -9731,6 +9818,10 @@ preemptively (e.g. a cache hit).
|
|||
*/
|
||||
issuedTokenCount?: number;
|
||||
}
|
||||
/**
|
||||
* Fired once security policy has been updated.
|
||||
*/
|
||||
export type policyUpdatedPayload = void;
|
||||
/**
|
||||
* Fired once when parsing the .wbn file has succeeded.
|
||||
The event contains the information about the web bundle contents.
|
||||
|
|
@ -11278,7 +11369,7 @@ as an ad.
|
|||
* All Permissions Policy features. This enum should match the one defined
|
||||
in third_party/blink/renderer/core/permissions_policy/permissions_policy_features.json5.
|
||||
*/
|
||||
export type PermissionsPolicyFeature = "accelerometer"|"ambient-light-sensor"|"attribution-reporting"|"autoplay"|"bluetooth"|"browsing-topics"|"camera"|"captured-surface-control"|"ch-dpr"|"ch-device-memory"|"ch-downlink"|"ch-ect"|"ch-prefers-color-scheme"|"ch-prefers-reduced-motion"|"ch-prefers-reduced-transparency"|"ch-rtt"|"ch-save-data"|"ch-ua"|"ch-ua-arch"|"ch-ua-bitness"|"ch-ua-platform"|"ch-ua-model"|"ch-ua-mobile"|"ch-ua-form-factors"|"ch-ua-full-version"|"ch-ua-full-version-list"|"ch-ua-platform-version"|"ch-ua-wow64"|"ch-viewport-height"|"ch-viewport-width"|"ch-width"|"clipboard-read"|"clipboard-write"|"compute-pressure"|"cross-origin-isolated"|"deferred-fetch"|"direct-sockets"|"display-capture"|"document-domain"|"encrypted-media"|"execution-while-out-of-viewport"|"execution-while-not-rendered"|"focus-without-user-activation"|"fullscreen"|"frobulate"|"gamepad"|"geolocation"|"gyroscope"|"hid"|"identity-credentials-get"|"idle-detection"|"interest-cohort"|"join-ad-interest-group"|"keyboard-map"|"local-fonts"|"magnetometer"|"microphone"|"midi"|"otp-credentials"|"payment"|"picture-in-picture"|"private-aggregation"|"private-state-token-issuance"|"private-state-token-redemption"|"publickey-credentials-create"|"publickey-credentials-get"|"run-ad-auction"|"screen-wake-lock"|"serial"|"shared-autofill"|"shared-storage"|"shared-storage-select-url"|"smart-card"|"speaker-selection"|"storage-access"|"sub-apps"|"sync-xhr"|"unload"|"usb"|"usb-unrestricted"|"vertical-scroll"|"web-printing"|"web-share"|"window-management"|"xr-spatial-tracking";
|
||||
export type PermissionsPolicyFeature = "accelerometer"|"ambient-light-sensor"|"attribution-reporting"|"autoplay"|"bluetooth"|"browsing-topics"|"camera"|"captured-surface-control"|"ch-dpr"|"ch-device-memory"|"ch-downlink"|"ch-ect"|"ch-prefers-color-scheme"|"ch-prefers-reduced-motion"|"ch-prefers-reduced-transparency"|"ch-rtt"|"ch-save-data"|"ch-ua"|"ch-ua-arch"|"ch-ua-bitness"|"ch-ua-platform"|"ch-ua-model"|"ch-ua-mobile"|"ch-ua-form-factors"|"ch-ua-full-version"|"ch-ua-full-version-list"|"ch-ua-platform-version"|"ch-ua-wow64"|"ch-viewport-height"|"ch-viewport-width"|"ch-width"|"clipboard-read"|"clipboard-write"|"compute-pressure"|"cross-origin-isolated"|"deferred-fetch"|"digital-credentials-get"|"direct-sockets"|"display-capture"|"document-domain"|"encrypted-media"|"execution-while-out-of-viewport"|"execution-while-not-rendered"|"focus-without-user-activation"|"fullscreen"|"frobulate"|"gamepad"|"geolocation"|"gyroscope"|"hid"|"identity-credentials-get"|"idle-detection"|"interest-cohort"|"join-ad-interest-group"|"keyboard-map"|"local-fonts"|"magnetometer"|"microphone"|"midi"|"otp-credentials"|"payment"|"picture-in-picture"|"private-aggregation"|"private-state-token-issuance"|"private-state-token-redemption"|"publickey-credentials-create"|"publickey-credentials-get"|"run-ad-auction"|"screen-wake-lock"|"serial"|"shared-autofill"|"shared-storage"|"shared-storage-select-url"|"smart-card"|"speaker-selection"|"storage-access"|"sub-apps"|"sync-xhr"|"unload"|"usb"|"usb-unrestricted"|"vertical-scroll"|"web-printing"|"web-share"|"window-management"|"xr-spatial-tracking";
|
||||
/**
|
||||
* Reason for a permissions policy feature to be disabled.
|
||||
*/
|
||||
|
|
@ -11866,7 +11957,7 @@ https://github.com/WICG/manifest-incubations/blob/gh-pages/scope_extensions-expl
|
|||
/**
|
||||
* List of not restored reasons for back-forward cache.
|
||||
*/
|
||||
export type BackForwardCacheNotRestoredReason = "NotPrimaryMainFrame"|"BackForwardCacheDisabled"|"RelatedActiveContentsExist"|"HTTPStatusNotOK"|"SchemeNotHTTPOrHTTPS"|"Loading"|"WasGrantedMediaAccess"|"DisableForRenderFrameHostCalled"|"DomainNotAllowed"|"HTTPMethodNotGET"|"SubframeIsNavigating"|"Timeout"|"CacheLimit"|"JavaScriptExecution"|"RendererProcessKilled"|"RendererProcessCrashed"|"SchedulerTrackedFeatureUsed"|"ConflictingBrowsingInstance"|"CacheFlushed"|"ServiceWorkerVersionActivation"|"SessionRestored"|"ServiceWorkerPostMessage"|"EnteredBackForwardCacheBeforeServiceWorkerHostAdded"|"RenderFrameHostReused_SameSite"|"RenderFrameHostReused_CrossSite"|"ServiceWorkerClaim"|"IgnoreEventAndEvict"|"HaveInnerContents"|"TimeoutPuttingInCache"|"BackForwardCacheDisabledByLowMemory"|"BackForwardCacheDisabledByCommandLine"|"NetworkRequestDatapipeDrainedAsBytesConsumer"|"NetworkRequestRedirected"|"NetworkRequestTimeout"|"NetworkExceedsBufferLimit"|"NavigationCancelledWhileRestoring"|"NotMostRecentNavigationEntry"|"BackForwardCacheDisabledForPrerender"|"UserAgentOverrideDiffers"|"ForegroundCacheLimit"|"BrowsingInstanceNotSwapped"|"BackForwardCacheDisabledForDelegate"|"UnloadHandlerExistsInMainFrame"|"UnloadHandlerExistsInSubFrame"|"ServiceWorkerUnregistration"|"CacheControlNoStore"|"CacheControlNoStoreCookieModified"|"CacheControlNoStoreHTTPOnlyCookieModified"|"NoResponseHead"|"Unknown"|"ActivationNavigationsDisallowedForBug1234857"|"ErrorDocument"|"FencedFramesEmbedder"|"CookieDisabled"|"HTTPAuthRequired"|"CookieFlushed"|"BroadcastChannelOnMessage"|"WebViewSettingsChanged"|"WebViewJavaScriptObjectChanged"|"WebViewMessageListenerInjected"|"WebViewSafeBrowsingAllowlistChanged"|"WebViewDocumentStartJavascriptChanged"|"WebSocket"|"WebTransport"|"WebRTC"|"MainResourceHasCacheControlNoStore"|"MainResourceHasCacheControlNoCache"|"SubresourceHasCacheControlNoStore"|"SubresourceHasCacheControlNoCache"|"ContainsPlugins"|"DocumentLoaded"|"OutstandingNetworkRequestOthers"|"RequestedMIDIPermission"|"RequestedAudioCapturePermission"|"RequestedVideoCapturePermission"|"RequestedBackForwardCacheBlockedSensors"|"RequestedBackgroundWorkPermission"|"BroadcastChannel"|"WebXR"|"SharedWorker"|"WebLocks"|"WebHID"|"WebShare"|"RequestedStorageAccessGrant"|"WebNfc"|"OutstandingNetworkRequestFetch"|"OutstandingNetworkRequestXHR"|"AppBanner"|"Printing"|"WebDatabase"|"PictureInPicture"|"Portal"|"SpeechRecognizer"|"IdleManager"|"PaymentManager"|"SpeechSynthesis"|"KeyboardLock"|"WebOTPService"|"OutstandingNetworkRequestDirectSocket"|"InjectedJavascript"|"InjectedStyleSheet"|"KeepaliveRequest"|"IndexedDBEvent"|"Dummy"|"JsNetworkRequestReceivedCacheControlNoStoreResource"|"WebRTCSticky"|"WebTransportSticky"|"WebSocketSticky"|"SmartCard"|"LiveMediaStreamTrack"|"UnloadHandler"|"ParserAborted"|"ContentSecurityHandler"|"ContentWebAuthenticationAPI"|"ContentFileChooser"|"ContentSerial"|"ContentFileSystemAccess"|"ContentMediaDevicesDispatcherHost"|"ContentWebBluetooth"|"ContentWebUSB"|"ContentMediaSessionService"|"ContentScreenReader"|"EmbedderPopupBlockerTabHelper"|"EmbedderSafeBrowsingTriggeredPopupBlocker"|"EmbedderSafeBrowsingThreatDetails"|"EmbedderAppBannerManager"|"EmbedderDomDistillerViewerSource"|"EmbedderDomDistillerSelfDeletingRequestDelegate"|"EmbedderOomInterventionTabHelper"|"EmbedderOfflinePage"|"EmbedderChromePasswordManagerClientBindCredentialManager"|"EmbedderPermissionRequestManager"|"EmbedderModalDialog"|"EmbedderExtensions"|"EmbedderExtensionMessaging"|"EmbedderExtensionMessagingForOpenPort"|"EmbedderExtensionSentMessageToCachedFrame"|"RequestedByWebViewClient";
|
||||
export type BackForwardCacheNotRestoredReason = "NotPrimaryMainFrame"|"BackForwardCacheDisabled"|"RelatedActiveContentsExist"|"HTTPStatusNotOK"|"SchemeNotHTTPOrHTTPS"|"Loading"|"WasGrantedMediaAccess"|"DisableForRenderFrameHostCalled"|"DomainNotAllowed"|"HTTPMethodNotGET"|"SubframeIsNavigating"|"Timeout"|"CacheLimit"|"JavaScriptExecution"|"RendererProcessKilled"|"RendererProcessCrashed"|"SchedulerTrackedFeatureUsed"|"ConflictingBrowsingInstance"|"CacheFlushed"|"ServiceWorkerVersionActivation"|"SessionRestored"|"ServiceWorkerPostMessage"|"EnteredBackForwardCacheBeforeServiceWorkerHostAdded"|"RenderFrameHostReused_SameSite"|"RenderFrameHostReused_CrossSite"|"ServiceWorkerClaim"|"IgnoreEventAndEvict"|"HaveInnerContents"|"TimeoutPuttingInCache"|"BackForwardCacheDisabledByLowMemory"|"BackForwardCacheDisabledByCommandLine"|"NetworkRequestDatapipeDrainedAsBytesConsumer"|"NetworkRequestRedirected"|"NetworkRequestTimeout"|"NetworkExceedsBufferLimit"|"NavigationCancelledWhileRestoring"|"NotMostRecentNavigationEntry"|"BackForwardCacheDisabledForPrerender"|"UserAgentOverrideDiffers"|"ForegroundCacheLimit"|"BrowsingInstanceNotSwapped"|"BackForwardCacheDisabledForDelegate"|"UnloadHandlerExistsInMainFrame"|"UnloadHandlerExistsInSubFrame"|"ServiceWorkerUnregistration"|"CacheControlNoStore"|"CacheControlNoStoreCookieModified"|"CacheControlNoStoreHTTPOnlyCookieModified"|"NoResponseHead"|"Unknown"|"ActivationNavigationsDisallowedForBug1234857"|"ErrorDocument"|"FencedFramesEmbedder"|"CookieDisabled"|"HTTPAuthRequired"|"CookieFlushed"|"BroadcastChannelOnMessage"|"WebViewSettingsChanged"|"WebViewJavaScriptObjectChanged"|"WebViewMessageListenerInjected"|"WebViewSafeBrowsingAllowlistChanged"|"WebViewDocumentStartJavascriptChanged"|"WebSocket"|"WebTransport"|"WebRTC"|"MainResourceHasCacheControlNoStore"|"MainResourceHasCacheControlNoCache"|"SubresourceHasCacheControlNoStore"|"SubresourceHasCacheControlNoCache"|"ContainsPlugins"|"DocumentLoaded"|"OutstandingNetworkRequestOthers"|"RequestedMIDIPermission"|"RequestedAudioCapturePermission"|"RequestedVideoCapturePermission"|"RequestedBackForwardCacheBlockedSensors"|"RequestedBackgroundWorkPermission"|"BroadcastChannel"|"WebXR"|"SharedWorker"|"WebLocks"|"WebHID"|"WebShare"|"RequestedStorageAccessGrant"|"WebNfc"|"OutstandingNetworkRequestFetch"|"OutstandingNetworkRequestXHR"|"AppBanner"|"Printing"|"WebDatabase"|"PictureInPicture"|"SpeechRecognizer"|"IdleManager"|"PaymentManager"|"SpeechSynthesis"|"KeyboardLock"|"WebOTPService"|"OutstandingNetworkRequestDirectSocket"|"InjectedJavascript"|"InjectedStyleSheet"|"KeepaliveRequest"|"IndexedDBEvent"|"Dummy"|"JsNetworkRequestReceivedCacheControlNoStoreResource"|"WebRTCSticky"|"WebTransportSticky"|"WebSocketSticky"|"SmartCard"|"LiveMediaStreamTrack"|"UnloadHandler"|"ParserAborted"|"ContentSecurityHandler"|"ContentWebAuthenticationAPI"|"ContentFileChooser"|"ContentSerial"|"ContentFileSystemAccess"|"ContentMediaDevicesDispatcherHost"|"ContentWebBluetooth"|"ContentWebUSB"|"ContentMediaSessionService"|"ContentScreenReader"|"EmbedderPopupBlockerTabHelper"|"EmbedderSafeBrowsingTriggeredPopupBlocker"|"EmbedderSafeBrowsingThreatDetails"|"EmbedderAppBannerManager"|"EmbedderDomDistillerViewerSource"|"EmbedderDomDistillerSelfDeletingRequestDelegate"|"EmbedderOomInterventionTabHelper"|"EmbedderOfflinePage"|"EmbedderChromePasswordManagerClientBindCredentialManager"|"EmbedderPermissionRequestManager"|"EmbedderModalDialog"|"EmbedderExtensions"|"EmbedderExtensionMessaging"|"EmbedderExtensionMessagingForOpenPort"|"EmbedderExtensionSentMessageToCachedFrame"|"RequestedByWebViewClient";
|
||||
/**
|
||||
* Types of not restored reasons for back-forward cache.
|
||||
*/
|
||||
|
|
@ -14053,6 +14144,25 @@ int
|
|||
eventReportWindows: AttributionReportingEventReportWindows;
|
||||
}
|
||||
export type AttributionReportingTriggerDataMatching = "exact"|"modulus";
|
||||
export interface AttributionReportingAggregatableDebugReportingData {
|
||||
keyPiece: UnsignedInt128AsBase16;
|
||||
/**
|
||||
* number instead of integer because not all uint32 can be represented by
|
||||
int
|
||||
*/
|
||||
value: number;
|
||||
types: string[];
|
||||
}
|
||||
export interface AttributionReportingAggregatableDebugReportingConfig {
|
||||
/**
|
||||
* number instead of integer because not all uint32 can be represented by
|
||||
int, only present for source registrations
|
||||
*/
|
||||
budget?: number;
|
||||
keyPiece: UnsignedInt128AsBase16;
|
||||
debugData: AttributionReportingAggregatableDebugReportingData[];
|
||||
aggregationCoordinatorOrigin?: string;
|
||||
}
|
||||
export interface AttributionReportingSourceRegistration {
|
||||
time: Network.TimeSinceEpoch;
|
||||
/**
|
||||
|
|
@ -14074,8 +14184,10 @@ int
|
|||
aggregationKeys: AttributionReportingAggregationKeysEntry[];
|
||||
debugKey?: UnsignedInt64AsBase10;
|
||||
triggerDataMatching: AttributionReportingTriggerDataMatching;
|
||||
destinationLimitPriority: SignedInt64AsBase10;
|
||||
aggregatableDebugReportingConfig: AttributionReportingAggregatableDebugReportingConfig;
|
||||
}
|
||||
export type AttributionReportingSourceRegistrationResult = "success"|"internalError"|"insufficientSourceCapacity"|"insufficientUniqueDestinationCapacity"|"excessiveReportingOrigins"|"prohibitedByBrowserPolicy"|"successNoised"|"destinationReportingLimitReached"|"destinationGlobalLimitReached"|"destinationBothLimitsReached"|"reportingOriginsPerSiteLimitReached"|"exceedsMaxChannelCapacity"|"exceedsMaxTriggerStateCardinality";
|
||||
export type AttributionReportingSourceRegistrationResult = "success"|"internalError"|"insufficientSourceCapacity"|"insufficientUniqueDestinationCapacity"|"excessiveReportingOrigins"|"prohibitedByBrowserPolicy"|"successNoised"|"destinationReportingLimitReached"|"destinationGlobalLimitReached"|"destinationBothLimitsReached"|"reportingOriginsPerSiteLimitReached"|"exceedsMaxChannelCapacity"|"exceedsMaxTriggerStateCardinality"|"destinationPerDayReportingLimitReached";
|
||||
export type AttributionReportingSourceRegistrationTimeConfig = "include"|"exclude";
|
||||
export interface AttributionReportingAggregatableValueDictEntry {
|
||||
key: string;
|
||||
|
|
@ -14084,6 +14196,7 @@ int
|
|||
int
|
||||
*/
|
||||
value: number;
|
||||
filteringId: UnsignedInt64AsBase10;
|
||||
}
|
||||
export interface AttributionReportingAggregatableValueEntry {
|
||||
values: AttributionReportingAggregatableValueDictEntry[];
|
||||
|
|
@ -14111,10 +14224,12 @@ int
|
|||
eventTriggerData: AttributionReportingEventTriggerData[];
|
||||
aggregatableTriggerData: AttributionReportingAggregatableTriggerData[];
|
||||
aggregatableValues: AttributionReportingAggregatableValueEntry[];
|
||||
aggregatableFilteringIdMaxBytes: number;
|
||||
debugReporting: boolean;
|
||||
aggregationCoordinatorOrigin?: string;
|
||||
sourceRegistrationTimeConfig: AttributionReportingSourceRegistrationTimeConfig;
|
||||
triggerContextId?: string;
|
||||
aggregatableDebugReportingConfig: AttributionReportingAggregatableDebugReportingConfig;
|
||||
}
|
||||
export type AttributionReportingEventLevelResult = "success"|"successDroppedLowerPriority"|"internalError"|"noCapacityForAttributionDestination"|"noMatchingSources"|"deduplicated"|"excessiveAttributions"|"priorityTooLow"|"neverAttributedSource"|"excessiveReportingOrigins"|"noMatchingSourceFilterData"|"prohibitedByBrowserPolicy"|"noMatchingConfigurations"|"excessiveReports"|"falselyAttributedSource"|"reportWindowPassed"|"notRegistered"|"reportWindowNotStarted"|"noMatchingTriggerData";
|
||||
export type AttributionReportingAggregatableResult = "success"|"internalError"|"noCapacityForAttributionDestination"|"noMatchingSources"|"excessiveAttributions"|"excessiveReportingOrigins"|"noHistograms"|"insufficientBudget"|"noMatchingSourceFilterData"|"notRegistered"|"prohibitedByBrowserPolicy"|"deduplicated"|"reportWindowPassed"|"excessiveReports";
|
||||
|
|
@ -14980,7 +15095,7 @@ supported.
|
|||
browserContextId?: Browser.BrowserContextID;
|
||||
/**
|
||||
* Provides additional details for specific target types. For example, for
|
||||
the type of "page", this may be set to "portal" or "prerender".
|
||||
the type of "page", this may be set to "prerender".
|
||||
*/
|
||||
subtype?: string;
|
||||
}
|
||||
|
|
@ -16807,7 +16922,7 @@ possible for multiple rule sets and links to trigger a single attempt.
|
|||
/**
|
||||
* List of FinalStatus reasons for Prerender2.
|
||||
*/
|
||||
export type PrerenderFinalStatus = "Activated"|"Destroyed"|"LowEndDevice"|"InvalidSchemeRedirect"|"InvalidSchemeNavigation"|"NavigationRequestBlockedByCsp"|"MainFrameNavigation"|"MojoBinderPolicy"|"RendererProcessCrashed"|"RendererProcessKilled"|"Download"|"TriggerDestroyed"|"NavigationNotCommitted"|"NavigationBadHttpStatus"|"ClientCertRequested"|"NavigationRequestNetworkError"|"CancelAllHostsForTesting"|"DidFailLoad"|"Stop"|"SslCertificateError"|"LoginAuthRequested"|"UaChangeRequiresReload"|"BlockedByClient"|"AudioOutputDeviceRequested"|"MixedContent"|"TriggerBackgrounded"|"MemoryLimitExceeded"|"DataSaverEnabled"|"TriggerUrlHasEffectiveUrl"|"ActivatedBeforeStarted"|"InactivePageRestriction"|"StartFailed"|"TimeoutBackgrounded"|"CrossSiteRedirectInInitialNavigation"|"CrossSiteNavigationInInitialNavigation"|"SameSiteCrossOriginRedirectNotOptInInInitialNavigation"|"SameSiteCrossOriginNavigationNotOptInInInitialNavigation"|"ActivationNavigationParameterMismatch"|"ActivatedInBackground"|"EmbedderHostDisallowed"|"ActivationNavigationDestroyedBeforeSuccess"|"TabClosedByUserGesture"|"TabClosedWithoutUserGesture"|"PrimaryMainFrameRendererProcessCrashed"|"PrimaryMainFrameRendererProcessKilled"|"ActivationFramePolicyNotCompatible"|"PreloadingDisabled"|"BatterySaverEnabled"|"ActivatedDuringMainFrameNavigation"|"PreloadingUnsupportedByWebContents"|"CrossSiteRedirectInMainFrameNavigation"|"CrossSiteNavigationInMainFrameNavigation"|"SameSiteCrossOriginRedirectNotOptInInMainFrameNavigation"|"SameSiteCrossOriginNavigationNotOptInInMainFrameNavigation"|"MemoryPressureOnTrigger"|"MemoryPressureAfterTriggered"|"PrerenderingDisabledByDevTools"|"SpeculationRuleRemoved"|"ActivatedWithAuxiliaryBrowsingContexts"|"MaxNumOfRunningEagerPrerendersExceeded"|"MaxNumOfRunningNonEagerPrerendersExceeded"|"MaxNumOfRunningEmbedderPrerendersExceeded"|"PrerenderingUrlHasEffectiveUrl"|"RedirectedPrerenderingUrlHasEffectiveUrl"|"ActivationUrlHasEffectiveUrl"|"JavaScriptInterfaceAdded"|"JavaScriptInterfaceRemoved"|"AllPrerenderingCanceled";
|
||||
export type PrerenderFinalStatus = "Activated"|"Destroyed"|"LowEndDevice"|"InvalidSchemeRedirect"|"InvalidSchemeNavigation"|"NavigationRequestBlockedByCsp"|"MainFrameNavigation"|"MojoBinderPolicy"|"RendererProcessCrashed"|"RendererProcessKilled"|"Download"|"TriggerDestroyed"|"NavigationNotCommitted"|"NavigationBadHttpStatus"|"ClientCertRequested"|"NavigationRequestNetworkError"|"CancelAllHostsForTesting"|"DidFailLoad"|"Stop"|"SslCertificateError"|"LoginAuthRequested"|"UaChangeRequiresReload"|"BlockedByClient"|"AudioOutputDeviceRequested"|"MixedContent"|"TriggerBackgrounded"|"MemoryLimitExceeded"|"DataSaverEnabled"|"TriggerUrlHasEffectiveUrl"|"ActivatedBeforeStarted"|"InactivePageRestriction"|"StartFailed"|"TimeoutBackgrounded"|"CrossSiteRedirectInInitialNavigation"|"CrossSiteNavigationInInitialNavigation"|"SameSiteCrossOriginRedirectNotOptInInInitialNavigation"|"SameSiteCrossOriginNavigationNotOptInInInitialNavigation"|"ActivationNavigationParameterMismatch"|"ActivatedInBackground"|"EmbedderHostDisallowed"|"ActivationNavigationDestroyedBeforeSuccess"|"TabClosedByUserGesture"|"TabClosedWithoutUserGesture"|"PrimaryMainFrameRendererProcessCrashed"|"PrimaryMainFrameRendererProcessKilled"|"ActivationFramePolicyNotCompatible"|"PreloadingDisabled"|"BatterySaverEnabled"|"ActivatedDuringMainFrameNavigation"|"PreloadingUnsupportedByWebContents"|"CrossSiteRedirectInMainFrameNavigation"|"CrossSiteNavigationInMainFrameNavigation"|"SameSiteCrossOriginRedirectNotOptInInMainFrameNavigation"|"SameSiteCrossOriginNavigationNotOptInInMainFrameNavigation"|"MemoryPressureOnTrigger"|"MemoryPressureAfterTriggered"|"PrerenderingDisabledByDevTools"|"SpeculationRuleRemoved"|"ActivatedWithAuxiliaryBrowsingContexts"|"MaxNumOfRunningEagerPrerendersExceeded"|"MaxNumOfRunningNonEagerPrerendersExceeded"|"MaxNumOfRunningEmbedderPrerendersExceeded"|"PrerenderingUrlHasEffectiveUrl"|"RedirectedPrerenderingUrlHasEffectiveUrl"|"ActivationUrlHasEffectiveUrl"|"JavaScriptInterfaceAdded"|"JavaScriptInterfaceRemoved"|"AllPrerenderingCanceled"|"WindowClosed";
|
||||
/**
|
||||
* Preloading status values, see also PreloadingTriggeringOutcome. This
|
||||
status is shared by prefetchStatusUpdated and prerenderStatusUpdated.
|
||||
|
|
@ -17021,6 +17136,10 @@ https://www.iana.org/assignments/media-types/media-types.xhtml
|
|||
accepts: FileHandlerAccept[];
|
||||
displayName: string;
|
||||
}
|
||||
/**
|
||||
* If user prefers opening the app in browser or an app window.
|
||||
*/
|
||||
export type DisplayMode = "standalone"|"browser";
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -17061,7 +17180,7 @@ manifestId.
|
|||
export type installReturnValue = {
|
||||
}
|
||||
/**
|
||||
* Uninstals the given manifest_id and closes any opened app windows.
|
||||
* Uninstalls the given manifest_id and closes any opened app windows.
|
||||
*/
|
||||
export type uninstallParameters = {
|
||||
manifestId: string;
|
||||
|
|
@ -17090,7 +17209,7 @@ the files. The API returns one or more page Target.TargetIDs which can be
|
|||
used to attach to via Target.attachToTarget or similar APIs.
|
||||
If some files in the parameters cannot be handled by the web app, they will
|
||||
be ignored. If none of the files can be handled, this API returns an error.
|
||||
If no files provided as the parameter, this API also returns an error.
|
||||
If no files are provided as the parameter, this API also returns an error.
|
||||
|
||||
According to the definition of the file handlers in the manifest file, one
|
||||
Target.TargetID may represent a page handling one or more files. The order
|
||||
|
|
@ -17111,13 +17230,44 @@ TODO(crbug.com/339454034): Check the existences of the input files.
|
|||
/**
|
||||
* Opens the current page in its web app identified by the manifest id, needs
|
||||
to be called on a page target. This function returns immediately without
|
||||
waiting for the app finishing loading.
|
||||
waiting for the app to finish loading.
|
||||
*/
|
||||
export type openCurrentPageInAppParameters = {
|
||||
manifestId: string;
|
||||
}
|
||||
export type openCurrentPageInAppReturnValue = {
|
||||
}
|
||||
/**
|
||||
* Changes user settings of the web app identified by its manifestId. If the
|
||||
app was not installed, this command returns an error. Unset parameters will
|
||||
be ignored; unrecognized values will cause an error.
|
||||
|
||||
Unlike the ones defined in the manifest files of the web apps, these
|
||||
settings are provided by the browser and controlled by the users, they
|
||||
impact the way the browser handling the web apps.
|
||||
|
||||
See the comment of each parameter.
|
||||
*/
|
||||
export type changeAppUserSettingsParameters = {
|
||||
manifestId: string;
|
||||
/**
|
||||
* If user allows the links clicked on by the user in the app's scope, or
|
||||
extended scope if the manifest has scope extensions and the flags
|
||||
`DesktopPWAsLinkCapturingWithScopeExtensions` and
|
||||
`WebAppEnableScopeExtensions` are enabled.
|
||||
|
||||
Note, the API does not support resetting the linkCapturing to the
|
||||
initial value, uninstalling and installing the web app again will reset
|
||||
it.
|
||||
|
||||
TODO(crbug.com/339453269): Setting this value on ChromeOS is not
|
||||
supported yet.
|
||||
*/
|
||||
linkCapturing?: boolean;
|
||||
displayMode?: DisplayMode;
|
||||
}
|
||||
export type changeAppUserSettingsReturnValue = {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -19824,6 +19974,7 @@ Error was thrown.
|
|||
"Network.responseReceivedExtraInfo": Network.responseReceivedExtraInfoPayload;
|
||||
"Network.responseReceivedEarlyHints": Network.responseReceivedEarlyHintsPayload;
|
||||
"Network.trustTokenOperationDone": Network.trustTokenOperationDonePayload;
|
||||
"Network.policyUpdated": Network.policyUpdatedPayload;
|
||||
"Network.subresourceWebBundleMetadataReceived": Network.subresourceWebBundleMetadataReceivedPayload;
|
||||
"Network.subresourceWebBundleMetadataError": Network.subresourceWebBundleMetadataErrorPayload;
|
||||
"Network.subresourceWebBundleInnerResponseParsed": Network.subresourceWebBundleInnerResponseParsedPayload;
|
||||
|
|
@ -20139,6 +20290,8 @@ Error was thrown.
|
|||
"Emulation.getOverriddenSensorInformation": Emulation.getOverriddenSensorInformationParameters;
|
||||
"Emulation.setSensorOverrideEnabled": Emulation.setSensorOverrideEnabledParameters;
|
||||
"Emulation.setSensorOverrideReadings": Emulation.setSensorOverrideReadingsParameters;
|
||||
"Emulation.setPressureSourceOverrideEnabled": Emulation.setPressureSourceOverrideEnabledParameters;
|
||||
"Emulation.setPressureStateOverride": Emulation.setPressureStateOverrideParameters;
|
||||
"Emulation.setIdleOverride": Emulation.setIdleOverrideParameters;
|
||||
"Emulation.clearIdleOverride": Emulation.clearIdleOverrideParameters;
|
||||
"Emulation.setNavigatorOverrides": Emulation.setNavigatorOverridesParameters;
|
||||
|
|
@ -20159,6 +20312,7 @@ Error was thrown.
|
|||
"IO.close": IO.closeParameters;
|
||||
"IO.read": IO.readParameters;
|
||||
"IO.resolveBlob": IO.resolveBlobParameters;
|
||||
"FileSystem.getDirectory": FileSystem.getDirectoryParameters;
|
||||
"IndexedDB.clearObjectStore": IndexedDB.clearObjectStoreParameters;
|
||||
"IndexedDB.deleteDatabase": IndexedDB.deleteDatabaseParameters;
|
||||
"IndexedDB.deleteObjectStoreEntries": IndexedDB.deleteObjectStoreEntriesParameters;
|
||||
|
|
@ -20461,6 +20615,7 @@ Error was thrown.
|
|||
"PWA.launch": PWA.launchParameters;
|
||||
"PWA.launchFilesInApp": PWA.launchFilesInAppParameters;
|
||||
"PWA.openCurrentPageInApp": PWA.openCurrentPageInAppParameters;
|
||||
"PWA.changeAppUserSettings": PWA.changeAppUserSettingsParameters;
|
||||
"Console.clearMessages": Console.clearMessagesParameters;
|
||||
"Console.disable": Console.disableParameters;
|
||||
"Console.enable": Console.enableParameters;
|
||||
|
|
@ -20735,6 +20890,8 @@ Error was thrown.
|
|||
"Emulation.getOverriddenSensorInformation": Emulation.getOverriddenSensorInformationReturnValue;
|
||||
"Emulation.setSensorOverrideEnabled": Emulation.setSensorOverrideEnabledReturnValue;
|
||||
"Emulation.setSensorOverrideReadings": Emulation.setSensorOverrideReadingsReturnValue;
|
||||
"Emulation.setPressureSourceOverrideEnabled": Emulation.setPressureSourceOverrideEnabledReturnValue;
|
||||
"Emulation.setPressureStateOverride": Emulation.setPressureStateOverrideReturnValue;
|
||||
"Emulation.setIdleOverride": Emulation.setIdleOverrideReturnValue;
|
||||
"Emulation.clearIdleOverride": Emulation.clearIdleOverrideReturnValue;
|
||||
"Emulation.setNavigatorOverrides": Emulation.setNavigatorOverridesReturnValue;
|
||||
|
|
@ -20755,6 +20912,7 @@ Error was thrown.
|
|||
"IO.close": IO.closeReturnValue;
|
||||
"IO.read": IO.readReturnValue;
|
||||
"IO.resolveBlob": IO.resolveBlobReturnValue;
|
||||
"FileSystem.getDirectory": FileSystem.getDirectoryReturnValue;
|
||||
"IndexedDB.clearObjectStore": IndexedDB.clearObjectStoreReturnValue;
|
||||
"IndexedDB.deleteDatabase": IndexedDB.deleteDatabaseReturnValue;
|
||||
"IndexedDB.deleteObjectStoreEntries": IndexedDB.deleteObjectStoreEntriesReturnValue;
|
||||
|
|
@ -21057,6 +21215,7 @@ Error was thrown.
|
|||
"PWA.launch": PWA.launchReturnValue;
|
||||
"PWA.launchFilesInApp": PWA.launchFilesInAppReturnValue;
|
||||
"PWA.openCurrentPageInApp": PWA.openCurrentPageInAppReturnValue;
|
||||
"PWA.changeAppUserSettings": PWA.changeAppUserSettingsReturnValue;
|
||||
"Console.clearMessages": Console.clearMessagesReturnValue;
|
||||
"Console.disable": Console.disableReturnValue;
|
||||
"Console.enable": Console.enableReturnValue;
|
||||
|
|
|
|||
24
packages/playwright-core/types/types.d.ts
vendored
24
packages/playwright-core/types/types.d.ts
vendored
|
|
@ -13172,8 +13172,8 @@ export interface BrowserType<Unused = {}> {
|
|||
*
|
||||
* An array of client certificates to be used. Each certificate object must have both `certPath` and `keyPath` or a
|
||||
* single `pfxPath` to load the client certificate. Optionally, `passphrase` property should be provided if the
|
||||
* certficiate is encrypted. If the certificate is valid only for specific origins, the `origin` property should be
|
||||
* provided with a glob pattern to match the origins that the certificate is valid for.
|
||||
* certficiate is encrypted. The `origin` property should be provided with an exact match to the request origin that
|
||||
* the certificate is valid for.
|
||||
*
|
||||
* **NOTE** Using Client Certificates in combination with Proxy Servers is not supported.
|
||||
*
|
||||
|
|
@ -13182,7 +13182,7 @@ export interface BrowserType<Unused = {}> {
|
|||
*/
|
||||
clientCertificates?: Array<{
|
||||
/**
|
||||
* Glob pattern to match against the request origin that the certificate is valid for.
|
||||
* Exact origin that the certificate is valid for. Origin includes `https` protocol, a hostname and optionally a port.
|
||||
*/
|
||||
origin: string;
|
||||
|
||||
|
|
@ -15583,8 +15583,8 @@ export interface APIRequest {
|
|||
*
|
||||
* An array of client certificates to be used. Each certificate object must have both `certPath` and `keyPath` or a
|
||||
* single `pfxPath` to load the client certificate. Optionally, `passphrase` property should be provided if the
|
||||
* certficiate is encrypted. If the certificate is valid only for specific origins, the `origin` property should be
|
||||
* provided with a glob pattern to match the origins that the certificate is valid for.
|
||||
* certficiate is encrypted. The `origin` property should be provided with an exact match to the request origin that
|
||||
* the certificate is valid for.
|
||||
*
|
||||
* **NOTE** Using Client Certificates in combination with Proxy Servers is not supported.
|
||||
*
|
||||
|
|
@ -15593,7 +15593,7 @@ export interface APIRequest {
|
|||
*/
|
||||
clientCertificates?: Array<{
|
||||
/**
|
||||
* Glob pattern to match against the request origin that the certificate is valid for.
|
||||
* Exact origin that the certificate is valid for. Origin includes `https` protocol, a hostname and optionally a port.
|
||||
*/
|
||||
origin: string;
|
||||
|
||||
|
|
@ -16776,8 +16776,8 @@ export interface Browser extends EventEmitter {
|
|||
*
|
||||
* An array of client certificates to be used. Each certificate object must have both `certPath` and `keyPath` or a
|
||||
* single `pfxPath` to load the client certificate. Optionally, `passphrase` property should be provided if the
|
||||
* certficiate is encrypted. If the certificate is valid only for specific origins, the `origin` property should be
|
||||
* provided with a glob pattern to match the origins that the certificate is valid for.
|
||||
* certficiate is encrypted. The `origin` property should be provided with an exact match to the request origin that
|
||||
* the certificate is valid for.
|
||||
*
|
||||
* **NOTE** Using Client Certificates in combination with Proxy Servers is not supported.
|
||||
*
|
||||
|
|
@ -16786,7 +16786,7 @@ export interface Browser extends EventEmitter {
|
|||
*/
|
||||
clientCertificates?: Array<{
|
||||
/**
|
||||
* Glob pattern to match against the request origin that the certificate is valid for.
|
||||
* Exact origin that the certificate is valid for. Origin includes `https` protocol, a hostname and optionally a port.
|
||||
*/
|
||||
origin: string;
|
||||
|
||||
|
|
@ -20226,8 +20226,8 @@ export interface BrowserContextOptions {
|
|||
*
|
||||
* An array of client certificates to be used. Each certificate object must have both `certPath` and `keyPath` or a
|
||||
* single `pfxPath` to load the client certificate. Optionally, `passphrase` property should be provided if the
|
||||
* certficiate is encrypted. If the certificate is valid only for specific origins, the `origin` property should be
|
||||
* provided with a glob pattern to match the origins that the certificate is valid for.
|
||||
* certficiate is encrypted. The `origin` property should be provided with an exact match to the request origin that
|
||||
* the certificate is valid for.
|
||||
*
|
||||
* **NOTE** Using Client Certificates in combination with Proxy Servers is not supported.
|
||||
*
|
||||
|
|
@ -20236,7 +20236,7 @@ export interface BrowserContextOptions {
|
|||
*/
|
||||
clientCertificates?: Array<{
|
||||
/**
|
||||
* Glob pattern to match against the request origin that the certificate is valid for.
|
||||
* Exact origin that the certificate is valid for. Origin includes `https` protocol, a hostname and optionally a port.
|
||||
*/
|
||||
origin: string;
|
||||
|
||||
|
|
|
|||
|
|
@ -355,7 +355,7 @@ const testOptions: [string, string][] = [
|
|||
['--max-failures <N>', `Stop after the first N failures`],
|
||||
['--no-deps', 'Do not run project dependencies'],
|
||||
['--output <dir>', `Folder for output artifacts (default: "test-results")`],
|
||||
['--only-changed [ref]', `Only run tests that have been changed between 'HEAD' and 'ref'. Defaults to running all uncommitted changes. Only supports Git.`],
|
||||
['--only-changed [ref]', `Only run test files that have been changed between 'HEAD' and 'ref'. Defaults to running all uncommitted changes. Only supports Git.`],
|
||||
['--pass-with-no-tests', `Makes test run succeed even if no tests were found`],
|
||||
['--project <project-name...>', `Only run tests from the specified list of projects, supports '*' wildcard (default: run all projects)`],
|
||||
['--quiet', `Suppress stdio`],
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ import type { Matcher } from '../util';
|
|||
import { Suite } from '../common/test';
|
||||
import { buildDependentProjects, buildTeardownToSetupsMap, filterProjects } from './projectUtils';
|
||||
import { FailureTracker } from './failureTracker';
|
||||
import { detectChangedTests } from './vcs';
|
||||
import { detectChangedTestFiles } from './vcs';
|
||||
|
||||
const readDirAsync = promisify(fs.readdir);
|
||||
|
||||
|
|
@ -232,7 +232,7 @@ function createLoadTask(mode: 'out-of-process' | 'in-process', options: { filter
|
|||
if (testRun.config.cliOnlyChanged && options.filterOnlyChanged) {
|
||||
for (const plugin of testRun.config.plugins)
|
||||
await plugin.instance?.populateDependencies?.();
|
||||
const changedFiles = await detectChangedTests(testRun.config.cliOnlyChanged, testRun.config.configDir);
|
||||
const changedFiles = await detectChangedTestFiles(testRun.config.cliOnlyChanged, testRun.config.configDir);
|
||||
cliOnlyChangedMatcher = file => changedFiles.has(file);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import childProcess from 'child_process';
|
|||
import { affectedTestFiles } from '../transform/compilationCache';
|
||||
import path from 'path';
|
||||
|
||||
export async function detectChangedTests(baseCommit: string, configDir: string): Promise<Set<string>> {
|
||||
export async function detectChangedTestFiles(baseCommit: string, configDir: string): Promise<Set<string>> {
|
||||
function gitFileList(command: string) {
|
||||
try {
|
||||
return childProcess.execSync(
|
||||
|
|
|
|||
4
packages/playwright/types/test.d.ts
vendored
4
packages/playwright/types/test.d.ts
vendored
|
|
@ -5208,8 +5208,8 @@ export interface PlaywrightTestOptions {
|
|||
*
|
||||
* An array of client certificates to be used. Each certificate object must have both `certPath` and `keyPath` or a
|
||||
* single `pfxPath` to load the client certificate. Optionally, `passphrase` property should be provided if the
|
||||
* certficiate is encrypted. If the certificate is valid only for specific origins, the `origin` property should be
|
||||
* provided with a glob pattern to match the origins that the certificate is valid for.
|
||||
* certficiate is encrypted. The `origin` property should be provided with an exact match to the request origin that
|
||||
* the certificate is valid for.
|
||||
*
|
||||
* **NOTE** Using Client Certificates in combination with Proxy Servers is not supported.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -107,8 +107,8 @@ export const renderAction = (
|
|||
{(showDuration || showBadges) && <div className='spacer'></div>}
|
||||
{showDuration && <div className='action-duration'>{time || <span className='codicon codicon-loading'></span>}</div>}
|
||||
{showBadges && <div className='action-icons' onClick={() => revealConsole?.()}>
|
||||
{!!errors && <div className='action-icon'><span className='codicon codicon-error'></span><span className="action-icon-value">{errors}</span></div>}
|
||||
{!!warnings && <div className='action-icon'><span className='codicon codicon-warning'></span><span className="action-icon-value">{warnings}</span></div>}
|
||||
{!!errors && <div className='action-icon'><span className='codicon codicon-error'></span><span className='action-icon-value'>{errors}</span></div>}
|
||||
{!!warnings && <div className='action-icon'><span className='codicon codicon-warning'></span><span className='action-icon-value'>{warnings}</span></div>}
|
||||
</div>}
|
||||
</>;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -73,6 +73,14 @@
|
|||
overflow: hidden;
|
||||
}
|
||||
|
||||
a.call-value {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a.call-value:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.call-value::before {
|
||||
content: '\00a0';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,12 @@ export const MetadataView: React.FunctionComponent<{
|
|||
{model.channel && <div className='call-line'>channel:<span className='call-value string' title={model.channel}>{model.channel}</span></div>}
|
||||
{model.platform && <div className='call-line'>platform:<span className='call-value string' title={model.platform}>{model.platform}</span></div>}
|
||||
{model.options.userAgent && <div className='call-line'>user agent:<span className='call-value datetime' title={model.options.userAgent}>{model.options.userAgent}</span></div>}
|
||||
{model.options.baseURL && (
|
||||
<>
|
||||
<div className='call-section' style={{ paddingTop: 2 }}>Config</div>
|
||||
<div className='call-line'>baseURL:<a className='call-value string' href={model.options.baseURL} title={model.options.baseURL} target='_blank' rel='noopener noreferrer'>{model.options.baseURL}</a></div>
|
||||
</>
|
||||
)}
|
||||
<div className='call-section'>Viewport</div>
|
||||
{model.options.viewport && <div className='call-line'>width:<span className='call-value number' title={String(!!model.options.viewport?.width)}>{model.options.viewport.width}</span></div>}
|
||||
{model.options.viewport && <div className='call-line'>height:<span className='call-value number' title={String(!!model.options.viewport?.height)}>{model.options.viewport.height}</span></div>}
|
||||
|
|
|
|||
|
|
@ -16,13 +16,22 @@
|
|||
|
||||
.settings-view {
|
||||
flex: none;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.settings-view .setting label {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
margin: 6px 2px;
|
||||
margin: 4px 2px;
|
||||
}
|
||||
|
||||
.settings-view .setting:first-of-type label {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.settings-view .setting:last-of-type label {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.settings-view .setting input {
|
||||
|
|
|
|||
|
|
@ -22,13 +22,11 @@ export const SettingsView: React.FunctionComponent<{
|
|||
settings: Setting<boolean>[],
|
||||
}> = ({ settings }) => {
|
||||
return <div className='vbox settings-view'>
|
||||
{settings.map(setting => {
|
||||
return <div key={setting.name} className='setting'>
|
||||
{settings.map(([value, set, title]) => {
|
||||
return <div key={title} className='setting'>
|
||||
<label>
|
||||
<input type='checkbox' checked={setting.value} onClick={() => {
|
||||
setting.set(!setting.value);
|
||||
}}/>
|
||||
{setting.title}
|
||||
<input type='checkbox' checked={value} onClick={() => set(!value)}/>
|
||||
{title}
|
||||
</label>
|
||||
</div>;
|
||||
})}
|
||||
|
|
|
|||
|
|
@ -25,11 +25,13 @@ import type { ContextEntry } from '../entries';
|
|||
import type { SourceLocation } from './modelUtil';
|
||||
import { idForAction, MultiTraceModel } from './modelUtil';
|
||||
import { Workbench } from './workbench';
|
||||
import { type Setting } from '@web/uiUtils';
|
||||
|
||||
export const TraceView: React.FC<{
|
||||
showRouteActionsSetting: Setting<boolean>,
|
||||
item: { treeItem?: TreeItem, testFile?: SourceLocation, testCase?: reporterTypes.TestCase },
|
||||
rootDir?: string,
|
||||
}> = ({ item, rootDir }) => {
|
||||
}> = ({ showRouteActionsSetting, item, rootDir }) => {
|
||||
const [model, setModel] = React.useState<{ model: MultiTraceModel, isLive: boolean } | undefined>();
|
||||
const [counter, setCounter] = React.useState(0);
|
||||
const pollTimer = React.useRef<NodeJS.Timeout | null>(null);
|
||||
|
|
@ -87,6 +89,7 @@ export const TraceView: React.FC<{
|
|||
|
||||
return <Workbench
|
||||
key='workbench'
|
||||
showRouteActionsSetting={showRouteActionsSetting}
|
||||
model={model?.model}
|
||||
showSourcesFirst={true}
|
||||
rootDir={rootDir}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,15 @@
|
|||
background-color: var(--vscode-sideBar-background);
|
||||
}
|
||||
|
||||
.ui-mode-sidebar > .settings-toolbar {
|
||||
border-top: 1px solid var(--vscode-panel-border);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.ui-mode-sidebar > .settings-view {
|
||||
margin: 0 0 3px 23px;
|
||||
}
|
||||
|
||||
.ui-mode-sidebar input[type=search] {
|
||||
flex: auto;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import { ToolbarButton } from '@web/components/toolbarButton';
|
|||
import { Toolbar } from '@web/components/toolbar';
|
||||
import type { XtermDataSource } from '@web/components/xtermWrapper';
|
||||
import { XtermWrapper } from '@web/components/xtermWrapper';
|
||||
import { toggleTheme } from '@web/theme';
|
||||
import { useDarkModeSetting } from '@web/theme';
|
||||
import { settings, useSetting } from '@web/uiUtils';
|
||||
import { statusEx, TestTree } from '@testIsomorphic/testTree';
|
||||
import type { TreeItem } from '@testIsomorphic/testTree';
|
||||
|
|
@ -39,6 +39,7 @@ import type { TestModel } from './uiModeModel';
|
|||
import { FiltersView } from './uiModeFiltersView';
|
||||
import { TestListView } from './uiModeTestListView';
|
||||
import { TraceView } from './uiModeTraceView';
|
||||
import { SettingsView } from './settingsView';
|
||||
|
||||
let xtermSize = { cols: 80, rows: 24 };
|
||||
const xtermDataSource: XtermDataSource = {
|
||||
|
|
@ -94,6 +95,37 @@ export const UIModeView: React.FC<{}> = ({
|
|||
const [hasBrowsers, setHasBrowsers] = React.useState(true);
|
||||
const [testServerConnection, setTestServerConnection] = React.useState<TestServerConnection>();
|
||||
const [teleSuiteUpdater, setTeleSuiteUpdater] = React.useState<TeleSuiteUpdater>();
|
||||
const [settingsVisible, setSettingsVisible] = React.useState(false);
|
||||
const [testingOptionsVisible, setTestingOptionsVisible] = React.useState(false);
|
||||
|
||||
const [runWorkers, setRunWorkers] = React.useState(queryParams.workers);
|
||||
const singleWorkerSetting = React.useMemo(() => {
|
||||
return [
|
||||
runWorkers === '1',
|
||||
(value: boolean) => {
|
||||
// When started with `--workers=1`, the setting allows to undo that.
|
||||
// Otherwise, fallback to the cli `--workers=X` argument.
|
||||
setRunWorkers(value ? '1' : (queryParams.workers === '1' ? undefined : queryParams.workers));
|
||||
},
|
||||
'Single worker',
|
||||
] as const;
|
||||
}, [runWorkers, setRunWorkers]);
|
||||
|
||||
const [runHeaded, setRunHeaded] = React.useState(queryParams.headed);
|
||||
const showBrowserSetting = React.useMemo(() => [runHeaded, setRunHeaded, 'Show browser'] as const, [runHeaded, setRunHeaded]);
|
||||
|
||||
const [runUpdateSnapshots, setRunUpdateSnapshots] = React.useState(queryParams.updateSnapshots);
|
||||
const updateSnapshotsSetting = React.useMemo(() => {
|
||||
return [
|
||||
runUpdateSnapshots === 'all',
|
||||
(value: boolean) => setRunUpdateSnapshots(value ? 'all' : 'missing'),
|
||||
'Update snapshots',
|
||||
] as const;
|
||||
}, [runUpdateSnapshots, setRunUpdateSnapshots]);
|
||||
|
||||
const [, , showRouteActionsSetting] = useSetting('show-route-actions', true, 'Show route actions');
|
||||
|
||||
const darkModeSetting = useDarkModeSetting();
|
||||
|
||||
const inputRef = React.useRef<HTMLInputElement>(null);
|
||||
|
||||
|
|
@ -294,11 +326,11 @@ export const UIModeView: React.FC<{}> = ({
|
|||
grepInvert: queryParams.grepInvert,
|
||||
testIds: [...testIds],
|
||||
projects: [...projectFilters].filter(([_, v]) => v).map(([p]) => p),
|
||||
workers: queryParams.workers,
|
||||
workers: runWorkers,
|
||||
timeout: queryParams.timeout,
|
||||
headed: queryParams.headed,
|
||||
headed: runHeaded,
|
||||
outputDir: queryParams.outputDir,
|
||||
updateSnapshots: queryParams.updateSnapshots,
|
||||
updateSnapshots: runUpdateSnapshots,
|
||||
reporters: queryParams.reporters,
|
||||
trace: 'on',
|
||||
});
|
||||
|
|
@ -310,7 +342,7 @@ export const UIModeView: React.FC<{}> = ({
|
|||
setTestModel({ ...testModel });
|
||||
setRunningState(undefined);
|
||||
});
|
||||
}, [projectFilters, runningState, testModel, testServerConnection]);
|
||||
}, [projectFilters, runningState, testModel, testServerConnection, runWorkers, runHeaded, runUpdateSnapshots]);
|
||||
|
||||
// Watch implementation.
|
||||
React.useEffect(() => {
|
||||
|
|
@ -418,14 +450,13 @@ export const UIModeView: React.FC<{}> = ({
|
|||
<XtermWrapper source={xtermDataSource}></XtermWrapper>
|
||||
</div>
|
||||
<div className={'vbox' + (isShowingOutput ? ' hidden' : '')}>
|
||||
<TraceView item={selectedItem} rootDir={testModel?.config?.rootDir} />
|
||||
<TraceView showRouteActionsSetting={showRouteActionsSetting} item={selectedItem} rootDir={testModel?.config?.rootDir} />
|
||||
</div>
|
||||
</div>
|
||||
<div className='vbox ui-mode-sidebar'>
|
||||
<Toolbar noShadow={true} noMinHeight={true}>
|
||||
<img src='playwright-logo.svg' alt='Playwright logo' />
|
||||
<div className='section-title'>Playwright</div>
|
||||
<ToolbarButton icon='color-mode' title='Toggle color mode' onClick={() => toggleTheme()} />
|
||||
<ToolbarButton icon='refresh' title='Reload' onClick={() => reloadTests()} disabled={isRunningTest || isLoading}></ToolbarButton>
|
||||
<ToolbarButton icon='terminal' title={'Toggle output — ' + (isMac ? '⌃`' : 'Ctrl + `')} toggled={isShowingOutput} onClick={() => { setIsShowingOutput(!isShowingOutput); }} />
|
||||
{!hasBrowsers && <ToolbarButton icon='lightbulb-autofix' style={{ color: 'var(--vscode-list-warningForeground)' }} title='Playwright browsers are missing' onClick={openInstallDialog} />}
|
||||
|
|
@ -472,6 +503,31 @@ export const UIModeView: React.FC<{}> = ({
|
|||
requestedCollapseAllCount={collapseAllCount}
|
||||
setFilterText={setFilterText}
|
||||
/>
|
||||
<Toolbar noShadow={true} noMinHeight={true} className='settings-toolbar' onClick={() => setTestingOptionsVisible(!testingOptionsVisible)}>
|
||||
<span
|
||||
className={`codicon codicon-${testingOptionsVisible ? 'chevron-down' : 'chevron-right'}`}
|
||||
style={{ marginLeft: 5 }}
|
||||
title={testingOptionsVisible ? 'Hide Testing Options' : 'Show Testing Options'}
|
||||
/>
|
||||
<div className='section-title'>Testing Options</div>
|
||||
</Toolbar>
|
||||
{testingOptionsVisible && <SettingsView settings={[
|
||||
singleWorkerSetting,
|
||||
showBrowserSetting,
|
||||
updateSnapshotsSetting,
|
||||
]} />}
|
||||
<Toolbar noShadow={true} noMinHeight={true} className='settings-toolbar' onClick={() => setSettingsVisible(!settingsVisible)}>
|
||||
<span
|
||||
className={`codicon codicon-${settingsVisible ? 'chevron-down' : 'chevron-right'}`}
|
||||
style={{ marginLeft: 5 }}
|
||||
title={settingsVisible ? 'Hide Settings' : 'Show Settings'}
|
||||
/>
|
||||
<div className='section-title'>Settings</div>
|
||||
</Toolbar>
|
||||
{settingsVisible && <SettingsView settings={[
|
||||
darkModeSetting,
|
||||
showRouteActionsSetting,
|
||||
]} />}
|
||||
</div>
|
||||
</SplitView>
|
||||
</div>;
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ import { AttachmentsTab } from './attachmentsTab';
|
|||
import type { Boundaries } from '../geometry';
|
||||
import { InspectorTab } from './inspectorTab';
|
||||
import { ToolbarButton } from '@web/components/toolbarButton';
|
||||
import { useSetting, msToString } from '@web/uiUtils';
|
||||
import { useSetting, msToString, type Setting } from '@web/uiUtils';
|
||||
import type { Entry } from '@trace/har';
|
||||
import './workbench.css';
|
||||
import { testStatusIcon, testStatusText } from './testUtils';
|
||||
|
|
@ -53,8 +53,9 @@ export const Workbench: React.FunctionComponent<{
|
|||
isLive?: boolean,
|
||||
status?: UITestStatus,
|
||||
inert?: boolean,
|
||||
showRouteActionsSetting?: Setting<boolean>,
|
||||
openPage?: (url: string, target?: string) => Window | any,
|
||||
}> = ({ model, showSourcesFirst, rootDir, fallbackLocation, initialSelection, onSelectionChanged, isLive, status, inert, openPage }) => {
|
||||
}> = ({ showRouteActionsSetting, model, showSourcesFirst, rootDir, fallbackLocation, initialSelection, onSelectionChanged, isLive, status, inert, openPage }) => {
|
||||
const [selectedAction, setSelectedActionImpl] = React.useState<ActionTraceEventInContext | undefined>(undefined);
|
||||
const [revealedStack, setRevealedStack] = React.useState<StackFrame[] | undefined>(undefined);
|
||||
const [highlightedAction, setHighlightedAction] = React.useState<ActionTraceEventInContext | undefined>();
|
||||
|
|
@ -67,7 +68,11 @@ export const Workbench: React.FunctionComponent<{
|
|||
const activeAction = model ? highlightedAction || selectedAction : undefined;
|
||||
const [selectedTime, setSelectedTime] = React.useState<Boundaries | undefined>();
|
||||
const [sidebarLocation, setSidebarLocation] = useSetting<'bottom' | 'right'>('propertiesSidebarLocation', 'bottom');
|
||||
const [showRouteActions, , showRouteActionsSetting] = useSetting('show-route-actions', true, 'Show route actions');
|
||||
const [, , showRouteActionsSettingInternal] = useSetting(showRouteActionsSetting ? undefined : 'show-route-actions', true, 'Show route actions');
|
||||
|
||||
const showSettings = !showRouteActionsSetting;
|
||||
showRouteActionsSetting ||= showRouteActionsSettingInternal;
|
||||
const showRouteActions = showRouteActionsSetting[0];
|
||||
|
||||
const filteredActions = React.useMemo(() => {
|
||||
return (model?.actions || []).filter(action => showRouteActions || action.class !== 'Route');
|
||||
|
|
@ -229,6 +234,40 @@ export const Workbench: React.FunctionComponent<{
|
|||
else if (model && model.wallTime)
|
||||
time = Date.now() - model.wallTime;
|
||||
|
||||
const actionsTab: TabbedPaneTabModel = {
|
||||
id: 'actions',
|
||||
title: 'Actions',
|
||||
component: <div className='vbox'>
|
||||
{status && <div className='workbench-run-status'>
|
||||
<span className={`codicon ${testStatusIcon(status)}`}></span>
|
||||
<div>{testStatusText(status)}</div>
|
||||
<div className='spacer'></div>
|
||||
<div className='workbench-run-duration'>{time ? msToString(time) : ''}</div>
|
||||
</div>}
|
||||
<ActionList
|
||||
sdkLanguage={sdkLanguage}
|
||||
actions={filteredActions}
|
||||
selectedAction={model ? selectedAction : undefined}
|
||||
selectedTime={selectedTime}
|
||||
setSelectedTime={setSelectedTime}
|
||||
onSelected={onActionSelected}
|
||||
onHighlighted={setHighlightedAction}
|
||||
revealConsole={() => selectPropertiesTab('console')}
|
||||
isLive={isLive}
|
||||
/>
|
||||
</div>
|
||||
};
|
||||
const metadataTab: TabbedPaneTabModel = {
|
||||
id: 'metadata',
|
||||
title: 'Metadata',
|
||||
component: <MetadataView model={model}/>
|
||||
};
|
||||
const settingsTab: TabbedPaneTabModel = {
|
||||
id: 'settings',
|
||||
title: 'Settings',
|
||||
component: <SettingsView settings={[showRouteActionsSetting]}/>,
|
||||
};
|
||||
|
||||
return <div className='vbox workbench' {...(inert ? { inert: 'true' } : {})}>
|
||||
<Timeline
|
||||
model={model}
|
||||
|
|
@ -254,41 +293,7 @@ export const Workbench: React.FunctionComponent<{
|
|||
setHighlightedLocator={locatorPicked}
|
||||
openPage={openPage} />
|
||||
<TabbedPane
|
||||
tabs={[
|
||||
{
|
||||
id: 'actions',
|
||||
title: 'Actions',
|
||||
component: <div className='vbox'>
|
||||
{status && <div className='workbench-run-status'>
|
||||
<span className={`codicon ${testStatusIcon(status)}`}></span>
|
||||
<div>{testStatusText(status)}</div>
|
||||
<div className='spacer'></div>
|
||||
<div className='workbench-run-duration'>{time ? msToString(time) : ''}</div>
|
||||
</div>}
|
||||
<ActionList
|
||||
sdkLanguage={sdkLanguage}
|
||||
actions={filteredActions}
|
||||
selectedAction={model ? selectedAction : undefined}
|
||||
selectedTime={selectedTime}
|
||||
setSelectedTime={setSelectedTime}
|
||||
onSelected={onActionSelected}
|
||||
onHighlighted={setHighlightedAction}
|
||||
revealConsole={() => selectPropertiesTab('console')}
|
||||
isLive={isLive}
|
||||
/>
|
||||
</div>
|
||||
},
|
||||
{
|
||||
id: 'metadata',
|
||||
title: 'Metadata',
|
||||
component: <MetadataView model={model}/>
|
||||
},
|
||||
{
|
||||
id: 'settings',
|
||||
title: 'Settings',
|
||||
component: <SettingsView settings={[showRouteActionsSetting]}/>,
|
||||
}
|
||||
]}
|
||||
tabs={showSettings ? [actionsTab, metadataTab, settingsTab] : [actionsTab, metadataTab]}
|
||||
selectedTab={selectedNavigatorTab}
|
||||
setSelectedTab={setSelectedNavigatorTab}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ export type Size = { width: number, height: number };
|
|||
export type VERSION = 7;
|
||||
|
||||
export type BrowserContextEventOptions = {
|
||||
baseURL?: string,
|
||||
viewport?: Size,
|
||||
deviceScaleFactor?: number,
|
||||
isMobile?: boolean,
|
||||
|
|
|
|||
|
|
@ -20,12 +20,16 @@ import * as React from 'react';
|
|||
type ToolbarProps = {
|
||||
noShadow?: boolean;
|
||||
noMinHeight?: boolean;
|
||||
className?: string;
|
||||
onClick?: (e: React.MouseEvent) => void;
|
||||
};
|
||||
|
||||
export const Toolbar: React.FC<React.PropsWithChildren<ToolbarProps>> = ({
|
||||
noShadow,
|
||||
children,
|
||||
noMinHeight
|
||||
noMinHeight,
|
||||
className,
|
||||
onClick,
|
||||
}) => {
|
||||
return <div className={'toolbar' + (noShadow ? ' no-shadow' : '') + (noMinHeight ? ' no-min-height' : '')}>{children}</div>;
|
||||
return <div className={'toolbar' + (noShadow ? ' no-shadow' : '') + (noMinHeight ? ' no-min-height' : '') + ' ' + (className || '')} onClick={onClick}>{children}</div>;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { settings } from './uiUtils';
|
||||
import React from 'react';
|
||||
import { type Setting, settings } from './uiUtils';
|
||||
|
||||
export function applyTheme() {
|
||||
if ((document as any).playwrightThemeInitialized)
|
||||
|
|
@ -64,3 +65,13 @@ export function removeThemeListener(listener: (theme: Theme) => void) {
|
|||
export function currentTheme(): Theme {
|
||||
return document.body.classList.contains('dark-mode') ? 'dark-mode' : 'light-mode';
|
||||
}
|
||||
|
||||
export function useDarkModeSetting() {
|
||||
const [theme, setTheme] = React.useState(currentTheme() === 'dark-mode');
|
||||
return [theme, (value: boolean) => {
|
||||
const current = currentTheme() === 'dark-mode';
|
||||
if (current !== value)
|
||||
toggleTheme();
|
||||
setTheme(value);
|
||||
}, 'Dark mode'] as Setting<boolean>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -139,12 +139,7 @@ export function copy(text: string) {
|
|||
textArea.remove();
|
||||
}
|
||||
|
||||
export type Setting<T> = {
|
||||
value: T;
|
||||
set: (value: T) => void;
|
||||
name: string;
|
||||
title: string;
|
||||
};
|
||||
export type Setting<T> = readonly [T, (value: T) => void, string];
|
||||
|
||||
export function useSetting<S>(name: string | undefined, defaultValue: S, title?: string): [S, React.Dispatch<React.SetStateAction<S>>, Setting<S>] {
|
||||
if (name)
|
||||
|
|
@ -155,12 +150,7 @@ export function useSetting<S>(name: string | undefined, defaultValue: S, title?:
|
|||
settings.setObject(name, value);
|
||||
setValue(value);
|
||||
}, [name, setValue]);
|
||||
const setting = {
|
||||
value,
|
||||
set: setValueWrapper,
|
||||
name: name || '',
|
||||
title: title || name || '',
|
||||
};
|
||||
const setting = [value, setValueWrapper, title || name || ''] as Setting<S>;
|
||||
return [value, setValueWrapper, setting];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ class TraceViewerPage {
|
|||
consoleStacks: Locator;
|
||||
stackFrames: Locator;
|
||||
networkRequests: Locator;
|
||||
metadataTab: Locator;
|
||||
snapshotContainer: Locator;
|
||||
|
||||
constructor(public page: Page) {
|
||||
|
|
@ -57,6 +58,7 @@ class TraceViewerPage {
|
|||
this.stackFrames = page.getByTestId('stack-trace-list').locator('.list-view-entry');
|
||||
this.networkRequests = page.getByTestId('network-list').locator('.list-view-entry');
|
||||
this.snapshotContainer = page.locator('.snapshot-container iframe.snapshot-visible[name=snapshot]');
|
||||
this.metadataTab = page.locator('.metadata-view');
|
||||
}
|
||||
|
||||
async actionIconsText(action: string) {
|
||||
|
|
@ -93,6 +95,10 @@ class TraceViewerPage {
|
|||
await this.page.click('text="Network"');
|
||||
}
|
||||
|
||||
async showMetadataTab() {
|
||||
await this.page.click('text="Metadata"');
|
||||
}
|
||||
|
||||
@step
|
||||
async snapshotFrame(actionName: string, ordinal: number = 0, hasSubframe: boolean = false): Promise<FrameLocator> {
|
||||
await this.selectAction(actionName, ordinal);
|
||||
|
|
|
|||
|
|
@ -35,8 +35,12 @@ const __testHookLookup = (hostname: string): LookupAddress[] => {
|
|||
|
||||
let interceptedHostnameLookup: string | undefined;
|
||||
|
||||
it.beforeEach(() => {
|
||||
it.beforeEach(({ server }) => {
|
||||
interceptedHostnameLookup = undefined;
|
||||
// Force a new connection every time, so that we can intercept the hostname lookup.
|
||||
server.setExtraHeaders('/simple.json', {
|
||||
'Connection': 'close',
|
||||
});
|
||||
});
|
||||
|
||||
it('get should work', async ({ context, server }) => {
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ browserTest('should be able to get correct orientation angle on non-mobile devic
|
|||
it('should set window.screen.orientation.type for mobile devices', async ({ contextFactory, browserName, server, isMac }) => {
|
||||
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/31151' });
|
||||
it.skip(browserName === 'firefox', 'Firefox does not support mobile emulation');
|
||||
it.skip(isMac && parseInt(os.release().split('.')[0], 10) <= 21, 'WebKit on macOS 12 is frozen and does not support orientation.type override');
|
||||
it.skip(browserName === 'webkit' && isMac && parseInt(os.release().split('.')[0], 10) <= 21, 'WebKit on macOS 12 is frozen and does not support orientation.type override');
|
||||
const context = await contextFactory(devices['iPhone 14']);
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.PREFIX + '/index.html');
|
||||
|
|
|
|||
|
|
@ -408,6 +408,29 @@ for (const kind of ['launchServer', 'run-server'] as const) {
|
|||
}
|
||||
});
|
||||
|
||||
test('should reject waitForEvent before browser.close finishes', async ({ connect, startRemoteServer, server }) => {
|
||||
const remoteServer = await startRemoteServer(kind);
|
||||
const browser = await connect(remoteServer.wsEndpoint());
|
||||
const newPage = await browser.newPage();
|
||||
let rejected = false;
|
||||
const promise = newPage.waitForEvent('download').catch(() => rejected = true);
|
||||
await browser.close();
|
||||
expect(rejected).toBe(true);
|
||||
await promise;
|
||||
});
|
||||
|
||||
test('should reject waitForEvent before browser.onDisconnect fires', async ({ connect, startRemoteServer, server }) => {
|
||||
const remoteServer = await startRemoteServer(kind);
|
||||
const browser = await connect(remoteServer.wsEndpoint());
|
||||
const newPage = await browser.newPage();
|
||||
const log: string[] = [];
|
||||
const promise = newPage.waitForEvent('download').catch(() => log.push('rejected'));
|
||||
browser.on('disconnected', () => log.push('disconnected'));
|
||||
await remoteServer.close();
|
||||
await promise;
|
||||
await expect.poll(() => log).toEqual(['rejected', 'disconnected']);
|
||||
});
|
||||
|
||||
test('should respect selectors', async ({ playwright, connect, startRemoteServer }) => {
|
||||
const remoteServer = await startRemoteServer(kind);
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@ import url from 'url';
|
|||
import { contextTest as it, expect } from '../config/browserTest';
|
||||
import { hostPlatform } from '../../packages/playwright-core/src/utils/hostPlatform';
|
||||
|
||||
it('SharedArrayBuffer should work @smoke', async function({ contextFactory, httpsServer }) {
|
||||
it('SharedArrayBuffer should work @smoke', async function({ contextFactory, httpsServer, isMac, browserName }) {
|
||||
it.skip(browserName === 'webkit' && isMac && parseInt(os.release().split('.')[0], 10) <= 21, 'WebKit on macOS 12 is frozen and does not support SharedArrayBuffer');
|
||||
const context = await contextFactory({ ignoreHTTPSErrors: true });
|
||||
const page = await context.newPage();
|
||||
httpsServer.setRoute('/sharedarraybuffer', (req, res) => {
|
||||
|
|
|
|||
|
|
@ -15,26 +15,27 @@
|
|||
*/
|
||||
|
||||
import fs from 'fs';
|
||||
import http2 from 'http2';
|
||||
import type http2 from 'http2';
|
||||
import type http from 'http';
|
||||
import { expect, playwrightTest as base } from '../config/browserTest';
|
||||
import type net from 'net';
|
||||
import type { BrowserContextOptions } from 'packages/playwright-test';
|
||||
const { createHttpsServer } = require('../../packages/playwright-core/lib/utils');
|
||||
const { createHttpsServer, createHttp2Server } = require('../../packages/playwright-core/lib/utils');
|
||||
|
||||
type TestOptions = {
|
||||
startCCServer(options?: {
|
||||
http2?: boolean;
|
||||
enableHTTP1FallbackWhenUsingHttp2?: boolean;
|
||||
useFakeLocalhost?: boolean;
|
||||
}): Promise<string>,
|
||||
};
|
||||
|
||||
const test = base.extend<TestOptions>({
|
||||
startCCServer: async ({ asset, browserName }, use) => {
|
||||
startCCServer: async ({ asset }, use) => {
|
||||
process.env.PWTEST_UNSUPPORTED_CUSTOM_CA = asset('client-certificates/server/server_cert.pem');
|
||||
let server: http.Server | http2.Http2Server | undefined;
|
||||
let server: http.Server | http2.Http2SecureServer | undefined;
|
||||
await use(async options => {
|
||||
server = (options?.http2 ? http2.createSecureServer : createHttpsServer)({
|
||||
server = (options?.http2 ? createHttp2Server : createHttpsServer)({
|
||||
key: fs.readFileSync(asset('client-certificates/server/server_key.pem')),
|
||||
cert: fs.readFileSync(asset('client-certificates/server/server_cert.pem')),
|
||||
ca: [
|
||||
|
|
@ -42,23 +43,25 @@ const test = base.extend<TestOptions>({
|
|||
],
|
||||
requestCert: true,
|
||||
rejectUnauthorized: false,
|
||||
allowHTTP1: true,
|
||||
allowHTTP1: options?.enableHTTP1FallbackWhenUsingHttp2,
|
||||
}, (req: (http2.Http2ServerRequest | http.IncomingMessage), res: http2.Http2ServerResponse | http.ServerResponse) => {
|
||||
const tlsSocket = req.socket as import('tls').TLSSocket;
|
||||
const parts: { key: string, value: any }[] = [];
|
||||
parts.push({ key: 'alpn-protocol', value: tlsSocket.alpnProtocol });
|
||||
// @ts-expect-error https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/62336
|
||||
expect(['localhost', 'local.playwright'].includes((tlsSocket).servername)).toBe(true);
|
||||
const prefix = `ALPN protocol: ${tlsSocket.alpnProtocol}\n`;
|
||||
parts.push({ key: 'servername', value: tlsSocket.servername });
|
||||
const cert = tlsSocket.getPeerCertificate();
|
||||
if (tlsSocket.authorized) {
|
||||
res.writeHead(200, { 'Content-Type': 'text/html' });
|
||||
res.end(prefix + `Hello ${cert.subject.CN}, your certificate was issued by ${cert.issuer.CN}!`);
|
||||
parts.push({ key: 'message', value: `Hello ${cert.subject.CN}, your certificate was issued by ${cert.issuer.CN}!` });
|
||||
} else if (cert.subject) {
|
||||
res.writeHead(403, { 'Content-Type': 'text/html' });
|
||||
res.end(prefix + `Sorry ${cert.subject.CN}, certificates from ${cert.issuer.CN} are not welcome here.`);
|
||||
parts.push({ key: 'message', value: `Sorry ${cert.subject.CN}, certificates from ${cert.issuer.CN} are not welcome here.` });
|
||||
} else {
|
||||
res.writeHead(401, { 'Content-Type': 'text/html' });
|
||||
res.end(prefix + `Sorry, but you need to provide a client certificate to continue.`);
|
||||
parts.push({ key: 'message', value: `Sorry, but you need to provide a client certificate to continue.` });
|
||||
}
|
||||
res.end(parts.map(({ key, value }) => `<div data-testid="${key}">${value}</div>`).join(''));
|
||||
});
|
||||
await new Promise<void>(f => server.listen(0, 'localhost', () => f()));
|
||||
const host = options?.useFakeLocalhost ? 'local.playwright' : 'localhost';
|
||||
|
|
@ -179,7 +182,7 @@ test.describe('fetch', () => {
|
|||
await route.fulfill({ response });
|
||||
});
|
||||
await page.goto(serverURL);
|
||||
await expect(page.getByText('Hello Alice, your certificate was issued by localhost!')).toBeVisible();
|
||||
await expect(page.getByTestId('message')).toHaveText('Hello Alice, your certificate was issued by localhost!');
|
||||
await page.close();
|
||||
await request.dispose();
|
||||
});
|
||||
|
|
@ -216,7 +219,7 @@ test.describe('browser', () => {
|
|||
}],
|
||||
});
|
||||
await page.goto(serverURL);
|
||||
await expect(page.getByText('Sorry, but you need to provide a client certificate to continue.')).toBeVisible();
|
||||
await expect(page.getByTestId('message')).toHaveText('Sorry, but you need to provide a client certificate to continue.');
|
||||
await page.close();
|
||||
});
|
||||
|
||||
|
|
@ -230,7 +233,7 @@ test.describe('browser', () => {
|
|||
}],
|
||||
});
|
||||
await page.goto(serverURL);
|
||||
await expect(page.getByText('Sorry Bob, certificates from Bob are not welcome here')).toBeVisible();
|
||||
await expect(page.getByTestId('message')).toHaveText('Sorry Bob, certificates from Bob are not welcome here.');
|
||||
await page.close();
|
||||
});
|
||||
|
||||
|
|
@ -244,6 +247,20 @@ test.describe('browser', () => {
|
|||
}],
|
||||
});
|
||||
await page.goto(serverURL);
|
||||
await expect(page.getByTestId('message')).toHaveText('Hello Alice, your certificate was issued by localhost!');
|
||||
await page.close();
|
||||
});
|
||||
|
||||
test('should pass with matching certificates and trailing slash', async ({ browser, startCCServer, asset, browserName }) => {
|
||||
const serverURL = await startCCServer({ useFakeLocalhost: browserName === 'webkit' && process.platform === 'darwin' });
|
||||
const page = await browser.newPage({
|
||||
clientCertificates: [{
|
||||
origin: serverURL,
|
||||
certPath: asset('client-certificates/client/trusted/cert.pem'),
|
||||
keyPath: asset('client-certificates/client/trusted/key.pem'),
|
||||
}],
|
||||
});
|
||||
await page.goto(serverURL);
|
||||
await expect(page.getByText('Hello Alice, your certificate was issued by localhost!')).toBeVisible();
|
||||
await page.close();
|
||||
});
|
||||
|
|
@ -263,7 +280,8 @@ test.describe('browser', () => {
|
|||
|
||||
test('support http2', async ({ browser, startCCServer, asset, browserName }) => {
|
||||
test.skip(browserName === 'webkit' && process.platform === 'darwin', 'WebKit on macOS doesn\n proxy localhost');
|
||||
const serverURL = await startCCServer({ http2: true });
|
||||
const enableHTTP1FallbackWhenUsingHttp2 = browserName === 'webkit' && process.platform === 'linux';
|
||||
const serverURL = await startCCServer({ http2: true, enableHTTP1FallbackWhenUsingHttp2 });
|
||||
const page = await browser.newPage({
|
||||
clientCertificates: [{
|
||||
origin: new URL(serverURL).origin,
|
||||
|
|
@ -273,23 +291,24 @@ test.describe('browser', () => {
|
|||
});
|
||||
// TODO: We should investigate why http2 is not supported in WebKit on Linux.
|
||||
// https://bugs.webkit.org/show_bug.cgi?id=276990
|
||||
const expectedProtocol = browserName === 'webkit' && process.platform === 'linux' ? 'http/1.1' : 'h2';
|
||||
const expectedProtocol = enableHTTP1FallbackWhenUsingHttp2 ? 'http/1.1' : 'h2';
|
||||
{
|
||||
await page.goto(serverURL.replace('localhost', 'local.playwright'));
|
||||
await expect(page.getByText('Sorry, but you need to provide a client certificate to continue.')).toBeVisible();
|
||||
await expect(page.getByText(`ALPN protocol: ${expectedProtocol}`)).toBeVisible();
|
||||
await expect(page.getByTestId('message')).toHaveText('Sorry, but you need to provide a client certificate to continue.');
|
||||
await expect(page.getByTestId('alpn-protocol')).toHaveText(expectedProtocol);
|
||||
await expect(page.getByTestId('servername')).toHaveText('local.playwright');
|
||||
}
|
||||
{
|
||||
await page.goto(serverURL);
|
||||
await expect(page.getByText('Hello Alice, your certificate was issued by localhost!')).toBeVisible();
|
||||
await expect(page.getByText(`ALPN protocol: ${expectedProtocol}`)).toBeVisible();
|
||||
await expect(page.getByTestId('message')).toHaveText('Hello Alice, your certificate was issued by localhost!');
|
||||
await expect(page.getByTestId('alpn-protocol')).toHaveText(expectedProtocol);
|
||||
}
|
||||
await page.close();
|
||||
});
|
||||
|
||||
test('support http2 if the browser only supports http1.1', async ({ browserType, browserName, startCCServer, asset }) => {
|
||||
test.skip(browserName !== 'chromium');
|
||||
const serverURL = await startCCServer({ http2: true });
|
||||
const serverURL = await startCCServer({ http2: true, enableHTTP1FallbackWhenUsingHttp2: true });
|
||||
const browser = await browserType.launch({ args: ['--disable-http2'] });
|
||||
const page = await browser.newPage({
|
||||
clientCertificates: [{
|
||||
|
|
@ -300,17 +319,36 @@ test.describe('browser', () => {
|
|||
});
|
||||
{
|
||||
await page.goto(serverURL.replace('localhost', 'local.playwright'));
|
||||
await expect(page.getByText('Sorry, but you need to provide a client certificate to continue.')).toBeVisible();
|
||||
await expect(page.getByText('ALPN protocol: http/1.1')).toBeVisible();
|
||||
await expect(page.getByTestId('message')).toHaveText('Sorry, but you need to provide a client certificate to continue.');
|
||||
await expect(page.getByTestId('alpn-protocol')).toHaveText('http/1.1');
|
||||
}
|
||||
{
|
||||
await page.goto(serverURL);
|
||||
await expect(page.getByText('Hello Alice, your certificate was issued by localhost!')).toBeVisible();
|
||||
await expect(page.getByText('ALPN protocol: http/1.1')).toBeVisible();
|
||||
await expect(page.getByTestId('message')).toHaveText('Hello Alice, your certificate was issued by localhost!');
|
||||
await expect(page.getByTestId('alpn-protocol')).toHaveText('http/1.1');
|
||||
}
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
test('should return target connection errors when using http2', async ({ browser, startCCServer, asset, browserName }) => {
|
||||
test.skip(browserName === 'webkit' && process.platform === 'darwin', 'WebKit on macOS doesn\n proxy localhost');
|
||||
test.fixme(browserName === 'webkit' && process.platform === 'linux', 'WebKit on Linux does not support http2 https://bugs.webkit.org/show_bug.cgi?id=276990');
|
||||
test.skip(+process.versions.node.split('.')[0] < 20, 'http2.performServerHandshake is not supported in older Node.js versions');
|
||||
|
||||
process.env.PWTEST_UNSUPPORTED_CUSTOM_CA = asset('empty.html');
|
||||
const serverURL = await startCCServer({ http2: true });
|
||||
const page = await browser.newPage({
|
||||
clientCertificates: [{
|
||||
origin: 'https://just-there-that-the-client-certificates-proxy-server-is-getting-launched.com',
|
||||
certPath: asset('client-certificates/client/trusted/cert.pem'),
|
||||
keyPath: asset('client-certificates/client/trusted/key.pem'),
|
||||
}],
|
||||
});
|
||||
await page.goto(serverURL);
|
||||
await expect(page.getByText('Playwright client-certificate error: self-signed certificate')).toBeVisible();
|
||||
await page.close();
|
||||
});
|
||||
|
||||
test.describe('persistentContext', () => {
|
||||
test('validate input', async ({ launchPersistent }) => {
|
||||
test.slow();
|
||||
|
|
@ -328,7 +366,7 @@ test.describe('browser', () => {
|
|||
}],
|
||||
});
|
||||
await page.goto(serverURL);
|
||||
await expect(page.getByText('Hello Alice, your certificate was issued by localhost!')).toBeVisible();
|
||||
await expect(page.getByTestId('message')).toHaveText('Hello Alice, your certificate was issued by localhost!');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -18,11 +18,11 @@
|
|||
import { browserTest as it, expect } from '../config/browserTest';
|
||||
import * as path from 'path';
|
||||
import fs from 'fs';
|
||||
import http2 from 'http2';
|
||||
import type { BrowserContext, BrowserContextOptions } from 'playwright-core';
|
||||
import type { AddressInfo } from 'net';
|
||||
import type { Log } from '../../packages/trace/src/har';
|
||||
import { parseHar } from '../config/utils';
|
||||
const { createHttp2Server } = require('../../packages/playwright-core/lib/utils');
|
||||
|
||||
async function pageWithHar(contextFactory: (options?: BrowserContextOptions) => Promise<BrowserContext>, testInfo: any, options: { outputPath?: string, content?: 'embed' | 'attach' | 'omit', omitContent?: boolean } = {}) {
|
||||
const harPath = testInfo.outputPath(options.outputPath || 'test.har');
|
||||
|
|
@ -686,7 +686,7 @@ it('should return security details directly from response', async ({ contextFact
|
|||
});
|
||||
|
||||
it('should contain http2 for http2 requests', async ({ contextFactory }, testInfo) => {
|
||||
const server = http2.createSecureServer({
|
||||
const server = createHttp2Server({
|
||||
key: await fs.promises.readFile(path.join(__dirname, '..', 'config', 'testserver', 'key.pem')),
|
||||
cert: await fs.promises.readFile(path.join(__dirname, '..', 'config', 'testserver', 'cert.pem')),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -559,7 +559,7 @@ await page.GetByLabel("Coun\\"try").ClickAsync();`);
|
|||
]);
|
||||
});
|
||||
|
||||
test('should consume contextmenu events, despite a custom context menu', async ({ page, openRecorder }) => {
|
||||
test('should consume contextmenu events, despite a custom context menu', async ({ page, openRecorder, browserName, platform }) => {
|
||||
const recorder = await openRecorder();
|
||||
|
||||
await recorder.setContentAndWait(`
|
||||
|
|
@ -597,20 +597,36 @@ await page.GetByLabel("Coun\\"try").ClickAsync();`);
|
|||
recorder.trustedClick({ button: 'right' }),
|
||||
]);
|
||||
expect(message.text()).toBe('right-clicked');
|
||||
expect(await page.evaluate('log')).toEqual([
|
||||
// hover
|
||||
'button: pointermove',
|
||||
'button: mousemove',
|
||||
// trusted right click
|
||||
'button: pointerup',
|
||||
'button: pointermove',
|
||||
'button: mousemove',
|
||||
'button: pointerdown',
|
||||
'button: mousedown',
|
||||
'button: contextmenu',
|
||||
'menu: pointerup',
|
||||
'menu: mouseup'
|
||||
]);
|
||||
if (browserName === 'chromium' && platform === 'win32') {
|
||||
expect(await page.evaluate('log')).toEqual([
|
||||
// hover
|
||||
'button: pointermove',
|
||||
'button: mousemove',
|
||||
// trusted right click
|
||||
'button: pointermove',
|
||||
'button: mousemove',
|
||||
'button: pointerdown',
|
||||
'button: mousedown',
|
||||
'button: pointerup',
|
||||
'button: mouseup',
|
||||
'button: contextmenu',
|
||||
]);
|
||||
} else {
|
||||
expect(await page.evaluate('log')).toEqual([
|
||||
// hover
|
||||
'button: pointermove',
|
||||
'button: mousemove',
|
||||
// trusted right click
|
||||
'button: pointerup',
|
||||
'button: pointermove',
|
||||
'button: mousemove',
|
||||
'button: pointerdown',
|
||||
'button: mousedown',
|
||||
'button: contextmenu',
|
||||
'menu: pointerup',
|
||||
'menu: mouseup',
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
test('should assert value', async ({ openRecorder }) => {
|
||||
|
|
|
|||
|
|
@ -31,7 +31,9 @@ test.slow();
|
|||
let traceFile: string;
|
||||
|
||||
test.beforeAll(async function recordTrace({ browser, browserName, browserType, server }, workerInfo) {
|
||||
const context = await browser.newContext();
|
||||
const context = await browser.newContext({
|
||||
baseURL: 'https://example.com',
|
||||
});
|
||||
await context.tracing.start({ name: 'test', screenshots: true, snapshots: true, sources: true });
|
||||
const page = await context.newPage();
|
||||
await page.goto(`data:text/html,<!DOCTYPE html><html>Hello world</html>`);
|
||||
|
|
@ -1368,3 +1370,12 @@ test('should allow hiding route actions', {
|
|||
/route.fulfill/,
|
||||
]);
|
||||
});
|
||||
|
||||
test('should show baseURL in metadata pane', {
|
||||
annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/31847' },
|
||||
}, async ({ showTraceViewer }) => {
|
||||
const traceViewer = await showTraceViewer([traceFile]);
|
||||
await traceViewer.selectAction('page.evaluate');
|
||||
await traceViewer.showMetadataTab();
|
||||
await expect(traceViewer.metadataTab).toContainText('baseURL:https://example.com');
|
||||
});
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ it('should upload the file', async ({ page, server, asset }) => {
|
|||
|
||||
it('should upload a folder', async ({ page, server, browserName, headless, browserMajorVersion, isAndroid }) => {
|
||||
it.skip(isAndroid);
|
||||
it.skip(os.platform() === 'darwin' && parseInt(os.release().split('.')[0], 10) <= 21, 'WebKit on macOS-12 is frozen');
|
||||
it.skip(browserName === 'webkit' && os.platform() === 'darwin' && parseInt(os.release().split('.')[0], 10) <= 21, 'WebKit on macOS-12 is frozen');
|
||||
|
||||
await page.goto(server.PREFIX + '/input/folderupload.html');
|
||||
const input = await page.$('input');
|
||||
|
|
@ -70,9 +70,9 @@ it('should upload a folder', async ({ page, server, browserName, headless, brows
|
|||
}
|
||||
});
|
||||
|
||||
it('should upload a folder and throw for multiple directories', async ({ page, server, isAndroid }) => {
|
||||
it('should upload a folder and throw for multiple directories', async ({ page, server, isAndroid, browserName }) => {
|
||||
it.skip(isAndroid);
|
||||
it.skip(os.platform() === 'darwin' && parseInt(os.release().split('.')[0], 10) <= 21, 'WebKit on macOS-12 is frozen');
|
||||
it.skip(browserName === 'webkit' && os.platform() === 'darwin' && parseInt(os.release().split('.')[0], 10) <= 21, 'WebKit on macOS-12 is frozen');
|
||||
|
||||
await page.goto(server.PREFIX + '/input/folderupload.html');
|
||||
const input = await page.$('input');
|
||||
|
|
@ -89,9 +89,9 @@ it('should upload a folder and throw for multiple directories', async ({ page, s
|
|||
])).rejects.toThrow('Multiple directories are not supported');
|
||||
});
|
||||
|
||||
it('should throw if a directory and files are passed', async ({ page, server, isAndroid }) => {
|
||||
it('should throw if a directory and files are passed', async ({ page, server, isAndroid, browserName }) => {
|
||||
it.skip(isAndroid);
|
||||
it.skip(os.platform() === 'darwin' && parseInt(os.release().split('.')[0], 10) <= 21, 'WebKit on macOS-12 is frozen');
|
||||
it.skip(browserName === 'webkit' && os.platform() === 'darwin' && parseInt(os.release().split('.')[0], 10) <= 21, 'WebKit on macOS-12 is frozen');
|
||||
|
||||
await page.goto(server.PREFIX + '/input/folderupload.html');
|
||||
const input = await page.$('input');
|
||||
|
|
@ -106,9 +106,9 @@ it('should throw if a directory and files are passed', async ({ page, server, is
|
|||
])).rejects.toThrow('File paths must be all files or a single directory');
|
||||
});
|
||||
|
||||
it('should throw when uploading a folder in a normal file upload input', async ({ page, server, isAndroid }) => {
|
||||
it('should throw when uploading a folder in a normal file upload input', async ({ page, server, isAndroid, browserName }) => {
|
||||
it.skip(isAndroid);
|
||||
it.skip(os.platform() === 'darwin' && parseInt(os.release().split('.')[0], 10) <= 21, 'WebKit on macOS-12 is frozen');
|
||||
it.skip(browserName === 'webkit' && os.platform() === 'darwin' && parseInt(os.release().split('.')[0], 10) <= 21, 'WebKit on macOS-12 is frozen');
|
||||
|
||||
await page.goto(server.PREFIX + '/input/fileupload.html');
|
||||
const input = await page.$('input');
|
||||
|
|
@ -120,9 +120,9 @@ it('should throw when uploading a folder in a normal file upload input', async (
|
|||
await expect(input.setInputFiles(dir)).rejects.toThrow('File input does not support directories, pass individual files instead');
|
||||
});
|
||||
|
||||
it('should throw when uploading a file in a directory upload input', async ({ page, server, isAndroid, asset }) => {
|
||||
it('should throw when uploading a file in a directory upload input', async ({ page, server, isAndroid, asset, browserName }) => {
|
||||
it.skip(isAndroid);
|
||||
it.skip(os.platform() === 'darwin' && parseInt(os.release().split('.')[0], 10) <= 21, 'WebKit on macOS-12 is frozen');
|
||||
it.skip(browserName === 'webkit' && os.platform() === 'darwin' && parseInt(os.release().split('.')[0], 10) <= 21, 'WebKit on macOS-12 is frozen');
|
||||
|
||||
await page.goto(server.PREFIX + '/input/folderupload.html');
|
||||
const input = await page.$('input');
|
||||
|
|
|
|||
|
|
@ -234,6 +234,7 @@ test('should only show tests selected with --grep', async ({ runUITest }) => {
|
|||
const { page } = await runUITest(basicTestTree, undefined, {
|
||||
additionalArgs: ['--grep', 'fails'],
|
||||
});
|
||||
await expect.poll(dumpTestTree(page)).toContain('fails');
|
||||
await expect.poll(dumpTestTree(page)).not.toContain('passes');
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,8 @@ test('should work after theme switch', async ({ runUITest, writeFiles }) => {
|
|||
await page.getByTitle('Run all').click();
|
||||
await expect(page.getByTestId('output')).toContainText(`Hello world 1`);
|
||||
|
||||
await page.getByTitle('Toggle color mode').click();
|
||||
await page.getByText('Settings', { exact: true }).click();
|
||||
await page.getByLabel('Dark mode').click();
|
||||
await writeFiles({
|
||||
'a.test.ts': `
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ set -x
|
|||
|
||||
trap "cd $(pwd -P)" EXIT
|
||||
SCRIPT_PATH="$(cd "$(dirname "$0")" ; pwd -P)"
|
||||
NODE_VERSION="20.15.1" # autogenerated via ./update-playwright-driver-version.mjs
|
||||
NODE_VERSION="20.16.0" # autogenerated via ./update-playwright-driver-version.mjs
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
PACKAGE_VERSION=$(node -p "require('../../package.json').version")
|
||||
|
|
|
|||
Loading…
Reference in a new issue