Merge branch 'main' into expect-extendImmutable
This commit is contained in:
commit
5164a7e892
|
|
@ -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://aka.ms/playwright/discord)
|
||||
[](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://aka.ms/playwright/discord)
|
||||
|
||||
## [Documentation](https://playwright.dev) | [API reference](https://playwright.dev/docs/api/class-playwright)
|
||||
|
||||
|
|
@ -8,7 +8,7 @@ Playwright is a framework for Web Testing and Automation. It allows testing [Chr
|
|||
|
||||
| | Linux | macOS | Windows |
|
||||
| :--- | :---: | :---: | :---: |
|
||||
| Chromium <!-- GEN:chromium-version -->128.0.6613.36<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||
| Chromium <!-- GEN:chromium-version -->129.0.6668.22<!-- 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 -->129.0<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||
|
||||
|
|
|
|||
|
|
@ -80,14 +80,14 @@ By default, Playwright will look up a closest tsconfig for each imported file by
|
|||
|
||||
```sh
|
||||
# Playwright will choose tsconfig automatically
|
||||
npx playwrigh test
|
||||
npx playwright test
|
||||
```
|
||||
|
||||
Alternatively, you can specify a single tsconfig file to use in the command line, and Playwright will use it for all imported files, not only test files.
|
||||
|
||||
```sh
|
||||
# Pass a specific tsconfig
|
||||
npx playwrigh test --tsconfig=tsconfig.test.json
|
||||
npx playwright test --tsconfig=tsconfig.test.json
|
||||
```
|
||||
|
||||
## Manually compile tests with TypeScript
|
||||
|
|
|
|||
8
package-lock.json
generated
8
package-lock.json
generated
|
|
@ -6820,9 +6820,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/svelte": {
|
||||
"version": "4.2.9",
|
||||
"resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.9.tgz",
|
||||
"integrity": "sha512-hsoB/WZGEPFXeRRLPhPrbRz67PhP6sqYgvwcAs+gWdSQSvNDw+/lTeUJSWe5h2xC97Fz/8QxAOqItwBzNJPU8w==",
|
||||
"version": "4.2.19",
|
||||
"resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.19.tgz",
|
||||
"integrity": "sha512-IY1rnGr6izd10B0A8LqsBfmlT5OILVuZ7XsI0vdGPEvuonFV7NYEUK4dAkm9Zg2q0Um92kYjTpS1CAP3Nh/KWw==",
|
||||
"dependencies": {
|
||||
"@ampproject/remapping": "^2.2.1",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.15",
|
||||
|
|
@ -8060,7 +8060,7 @@
|
|||
"playwright": "cli.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"svelte": "^4.2.8"
|
||||
"svelte": "^4.2.19"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
|
|
|
|||
|
|
@ -75,11 +75,16 @@ export const AttachmentLink: React.FunctionComponent<{
|
|||
attachment: TestAttachment,
|
||||
href?: string,
|
||||
linkName?: string,
|
||||
}> = ({ attachment, href, linkName }) => {
|
||||
openInNewTab?: boolean,
|
||||
}> = ({ attachment, href, linkName, openInNewTab }) => {
|
||||
return <TreeItem title={<span>
|
||||
{attachment.contentType === kMissingContentType ? icons.warning() : icons.attachment()}
|
||||
{attachment.path && <a href={href || attachment.path} download={downloadFileNameForAttachment(attachment)}>{linkName || attachment.name}</a>}
|
||||
{!attachment.path && <span>{linkifyText(attachment.name)}</span>}
|
||||
{!attachment.path && (
|
||||
openInNewTab
|
||||
? <a href={URL.createObjectURL(new Blob([attachment.body!], { type: attachment.contentType }))} target='_blank' rel='noreferrer' onClick={e => e.stopPropagation()}>{attachment.name}</a>
|
||||
: <span>{linkifyText(attachment.name)}</span>
|
||||
)}
|
||||
</span>} loadChildren={attachment.body ? () => {
|
||||
return [<div key={1} className='attachment-body'><CopyToClipboard value={attachment.body!}/>{linkifyText(attachment.body!)}</div>];
|
||||
} : undefined} depth={0} style={{ lineHeight: '32px' }}></TreeItem>;
|
||||
|
|
|
|||
|
|
@ -67,15 +67,16 @@ export const TestResultView: React.FC<{
|
|||
anchor: 'video' | 'diff' | '',
|
||||
}> = ({ result, anchor }) => {
|
||||
|
||||
const { screenshots, videos, traces, otherAttachments, diffs } = React.useMemo(() => {
|
||||
const { screenshots, videos, traces, otherAttachments, diffs, htmls } = React.useMemo(() => {
|
||||
const attachments = result?.attachments || [];
|
||||
const screenshots = new Set(attachments.filter(a => a.contentType.startsWith('image/')));
|
||||
const videos = attachments.filter(a => a.name === 'video');
|
||||
const traces = attachments.filter(a => a.name === 'trace');
|
||||
const htmls = attachments.filter(a => a.contentType.startsWith('text/html'));
|
||||
const otherAttachments = new Set<TestAttachment>(attachments);
|
||||
[...screenshots, ...videos, ...traces].forEach(a => otherAttachments.delete(a));
|
||||
[...screenshots, ...videos, ...traces, ...htmls].forEach(a => otherAttachments.delete(a));
|
||||
const diffs = groupImageDiffs(screenshots);
|
||||
return { screenshots: [...screenshots], videos, traces, otherAttachments, diffs };
|
||||
return { screenshots: [...screenshots], videos, traces, otherAttachments, diffs, htmls };
|
||||
}, [result]);
|
||||
|
||||
const videoRef = React.useRef<HTMLDivElement>(null);
|
||||
|
|
@ -135,7 +136,10 @@ export const TestResultView: React.FC<{
|
|||
</div>)}
|
||||
</AutoChip>}
|
||||
|
||||
{!!otherAttachments.size && <AutoChip header='Attachments'>
|
||||
{!!(otherAttachments.size + htmls.length) && <AutoChip header='Attachments'>
|
||||
{[...htmls].map((a, i) => (
|
||||
<AttachmentLink key={`html-link-${i}`} attachment={a} openInNewTab />)
|
||||
)}
|
||||
{[...otherAttachments].map((a, i) => <AttachmentLink key={`attachment-link-${i}`} attachment={a}></AttachmentLink>)}
|
||||
</AutoChip>}
|
||||
</div>;
|
||||
|
|
|
|||
|
|
@ -3,15 +3,15 @@
|
|||
"browsers": [
|
||||
{
|
||||
"name": "chromium",
|
||||
"revision": "1131",
|
||||
"revision": "1133",
|
||||
"installByDefault": true,
|
||||
"browserVersion": "128.0.6613.36"
|
||||
"browserVersion": "129.0.6668.22"
|
||||
},
|
||||
{
|
||||
"name": "chromium-tip-of-tree",
|
||||
"revision": "1254",
|
||||
"revision": "1255",
|
||||
"installByDefault": false,
|
||||
"browserVersion": "130.0.6681.0"
|
||||
"browserVersion": "130.0.6684.0"
|
||||
},
|
||||
{
|
||||
"name": "firefox",
|
||||
|
|
|
|||
|
|
@ -1131,17 +1131,21 @@ using Audits.issueAdded event.
|
|||
}
|
||||
|
||||
/**
|
||||
* Defines commands and events for browser extensions. Available if the client
|
||||
is connected using the --remote-debugging-pipe flag and
|
||||
the --enable-unsafe-extension-debugging flag is set.
|
||||
* Defines commands and events for browser extensions.
|
||||
*/
|
||||
export module Extensions {
|
||||
/**
|
||||
* Storage areas.
|
||||
*/
|
||||
export type StorageArea = "session"|"local"|"sync"|"managed";
|
||||
|
||||
|
||||
/**
|
||||
* Installs an unpacked extension from the filesystem similar to
|
||||
--load-extension CLI flags. Returns extension ID once the extension
|
||||
has been installed.
|
||||
has been installed. Available if the client is connected using the
|
||||
--remote-debugging-pipe flag and the --enable-unsafe-extension-debugging
|
||||
flag is set.
|
||||
*/
|
||||
export type loadUnpackedParameters = {
|
||||
/**
|
||||
|
|
@ -1155,6 +1159,81 @@ has been installed.
|
|||
*/
|
||||
id: string;
|
||||
}
|
||||
/**
|
||||
* Gets data from extension storage in the given `storageArea`. If `keys` is
|
||||
specified, these are used to filter the result.
|
||||
*/
|
||||
export type getStorageItemsParameters = {
|
||||
/**
|
||||
* ID of extension.
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* StorageArea to retrieve data from.
|
||||
*/
|
||||
storageArea: StorageArea;
|
||||
/**
|
||||
* Keys to retrieve.
|
||||
*/
|
||||
keys?: string[];
|
||||
}
|
||||
export type getStorageItemsReturnValue = {
|
||||
data: { [key: string]: string };
|
||||
}
|
||||
/**
|
||||
* Removes `keys` from extension storage in the given `storageArea`.
|
||||
*/
|
||||
export type removeStorageItemsParameters = {
|
||||
/**
|
||||
* ID of extension.
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* StorageArea to remove data from.
|
||||
*/
|
||||
storageArea: StorageArea;
|
||||
/**
|
||||
* Keys to remove.
|
||||
*/
|
||||
keys: string[];
|
||||
}
|
||||
export type removeStorageItemsReturnValue = {
|
||||
}
|
||||
/**
|
||||
* Clears extension storage in the given `storageArea`.
|
||||
*/
|
||||
export type clearStorageItemsParameters = {
|
||||
/**
|
||||
* ID of extension.
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* StorageArea to remove data from.
|
||||
*/
|
||||
storageArea: StorageArea;
|
||||
}
|
||||
export type clearStorageItemsReturnValue = {
|
||||
}
|
||||
/**
|
||||
* Sets `values` in extension storage in the given `storageArea`. The provided `values`
|
||||
will be merged with existing values in the storage area.
|
||||
*/
|
||||
export type setStorageItemsParameters = {
|
||||
/**
|
||||
* ID of extension.
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* StorageArea to set data in.
|
||||
*/
|
||||
storageArea: StorageArea;
|
||||
/**
|
||||
* Values to set.
|
||||
*/
|
||||
values: { [key: string]: string };
|
||||
}
|
||||
export type setStorageItemsReturnValue = {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2532,16 +2611,6 @@ stylesheet rules) this rule came from.
|
|||
*/
|
||||
style: CSSStyle;
|
||||
}
|
||||
/**
|
||||
* CSS position-fallback rule representation.
|
||||
*/
|
||||
export interface CSSPositionFallbackRule {
|
||||
name: Value;
|
||||
/**
|
||||
* List of keyframes.
|
||||
*/
|
||||
tryRules: CSSTryRule[];
|
||||
}
|
||||
/**
|
||||
* CSS @position-try rule representation.
|
||||
*/
|
||||
|
|
@ -2888,10 +2957,6 @@ attributes) for a DOM node identified by `nodeId`.
|
|||
* A list of CSS keyframed animations matching this node.
|
||||
*/
|
||||
cssKeyframesRules?: CSSKeyframesRule[];
|
||||
/**
|
||||
* A list of CSS position fallbacks matching this node.
|
||||
*/
|
||||
cssPositionFallbackRules?: CSSPositionFallbackRule[];
|
||||
/**
|
||||
* A list of CSS @position-try rules matching this node, based on the position-try-fallbacks property.
|
||||
*/
|
||||
|
|
@ -3496,7 +3561,7 @@ front-end.
|
|||
/**
|
||||
* Pseudo element type.
|
||||
*/
|
||||
export type PseudoType = "first-line"|"first-letter"|"before"|"after"|"marker"|"backdrop"|"selection"|"search-text"|"target-text"|"spelling-error"|"grammar-error"|"highlight"|"first-line-inherited"|"scroll-marker"|"scroll-marker-group"|"scrollbar"|"scrollbar-thumb"|"scrollbar-button"|"scrollbar-track"|"scrollbar-track-piece"|"scrollbar-corner"|"resizer"|"input-list-button"|"view-transition"|"view-transition-group"|"view-transition-image-pair"|"view-transition-old"|"view-transition-new";
|
||||
export type PseudoType = "first-line"|"first-letter"|"before"|"after"|"marker"|"backdrop"|"selection"|"search-text"|"target-text"|"spelling-error"|"grammar-error"|"highlight"|"first-line-inherited"|"scroll-marker"|"scroll-marker-group"|"scroll-next-button"|"scroll-prev-button"|"scrollbar"|"scrollbar-thumb"|"scrollbar-button"|"scrollbar-track"|"scrollbar-track-piece"|"scrollbar-corner"|"resizer"|"input-list-button"|"view-transition"|"view-transition-group"|"view-transition-image-pair"|"view-transition-old"|"view-transition-new";
|
||||
/**
|
||||
* Shadow root type.
|
||||
*/
|
||||
|
|
@ -3646,6 +3711,13 @@ The property is always undefined now.
|
|||
compatibilityMode?: CompatibilityMode;
|
||||
assignedSlot?: BackendNode;
|
||||
}
|
||||
/**
|
||||
* A structure to hold the top-level node of a detached tree and an array of its retained descendants.
|
||||
*/
|
||||
export interface DetachedElementInfo {
|
||||
treeNode: Node;
|
||||
retainedNodeIds: NodeId[];
|
||||
}
|
||||
/**
|
||||
* A structure holding an RGBA color.
|
||||
*/
|
||||
|
|
@ -4693,6 +4765,17 @@ File wrapper.
|
|||
export type getFileInfoReturnValue = {
|
||||
path: string;
|
||||
}
|
||||
/**
|
||||
* Returns list of detached nodes
|
||||
*/
|
||||
export type getDetachedDomNodesParameters = {
|
||||
}
|
||||
export type getDetachedDomNodesReturnValue = {
|
||||
/**
|
||||
* The list of detached nodes
|
||||
*/
|
||||
detachedNodes: DetachedElementInfo[];
|
||||
}
|
||||
/**
|
||||
* Enables console to refer to the node with given id via $x (see Command Line API for more details
|
||||
$x functions).
|
||||
|
|
@ -11369,7 +11452,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"|"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";
|
||||
export type PermissionsPolicyFeature = "accelerometer"|"all-screens-capture"|"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"|"media-playback-while-not-visible"|"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.
|
||||
*/
|
||||
|
|
@ -11784,7 +11867,7 @@ Example URLs: http://www.google.com/file.html -> "google.com"
|
|||
*/
|
||||
fixed?: number;
|
||||
}
|
||||
export type ClientNavigationReason = "formSubmissionGet"|"formSubmissionPost"|"httpHeaderRefresh"|"scriptInitiated"|"metaTagRefresh"|"pageBlockInterstitial"|"reload"|"anchorClick";
|
||||
export type ClientNavigationReason = "anchorClick"|"formSubmissionGet"|"formSubmissionPost"|"httpHeaderRefresh"|"initialFrameNavigation"|"metaTagRefresh"|"other"|"pageBlockInterstitial"|"reload"|"scriptInitiated";
|
||||
export type ClientNavigationDisposition = "currentTab"|"newTab"|"newWindow"|"download";
|
||||
export interface InstallabilityErrorArgument {
|
||||
/**
|
||||
|
|
@ -12298,6 +12381,10 @@ when bfcache navigation fails.
|
|||
* Frame's new url.
|
||||
*/
|
||||
url: string;
|
||||
/**
|
||||
* Navigation type
|
||||
*/
|
||||
navigationType: "fragment"|"historyApi"|"other";
|
||||
}
|
||||
/**
|
||||
* Compressed image data requested by the `startScreencast`.
|
||||
|
|
@ -16922,7 +17009,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"|"WindowClosed";
|
||||
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"|"SlowNetwork"|"OtherPrerenderedPageActivated";
|
||||
/**
|
||||
* Preloading status values, see also PreloadingTriggeringOutcome. This
|
||||
status is shared by prefetchStatusUpdated and prerenderStatusUpdated.
|
||||
|
|
@ -17270,6 +17357,101 @@ supported yet.
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This domain allows configuring virtual Bluetooth devices to test
|
||||
the web-bluetooth API.
|
||||
*/
|
||||
export module BluetoothEmulation {
|
||||
/**
|
||||
* Indicates the various states of Central.
|
||||
*/
|
||||
export type CentralState = "absent"|"powered-off"|"powered-on";
|
||||
/**
|
||||
* Stores the manufacturer data
|
||||
*/
|
||||
export interface ManufacturerData {
|
||||
/**
|
||||
* Company identifier
|
||||
https://bitbucket.org/bluetooth-SIG/public/src/main/assigned_numbers/company_identifiers/company_identifiers.yaml
|
||||
https://usb.org/developers
|
||||
*/
|
||||
key: number;
|
||||
/**
|
||||
* Manufacturer-specific data
|
||||
*/
|
||||
data: binary;
|
||||
}
|
||||
/**
|
||||
* Stores the byte data of the advertisement packet sent by a Bluetooth device.
|
||||
*/
|
||||
export interface ScanRecord {
|
||||
name?: string;
|
||||
uuids?: string[];
|
||||
/**
|
||||
* Stores the external appearance description of the device.
|
||||
*/
|
||||
appearance?: number;
|
||||
/**
|
||||
* Stores the transmission power of a broadcasting device.
|
||||
*/
|
||||
txPower?: number;
|
||||
/**
|
||||
* Key is the company identifier and the value is an array of bytes of
|
||||
manufacturer specific data.
|
||||
*/
|
||||
manufacturerData?: ManufacturerData[];
|
||||
}
|
||||
/**
|
||||
* Stores the advertisement packet information that is sent by a Bluetooth device.
|
||||
*/
|
||||
export interface ScanEntry {
|
||||
deviceAddress: string;
|
||||
rssi: number;
|
||||
scanRecord: ScanRecord;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Enable the BluetoothEmulation domain.
|
||||
*/
|
||||
export type enableParameters = {
|
||||
/**
|
||||
* State of the simulated central.
|
||||
*/
|
||||
state: CentralState;
|
||||
}
|
||||
export type enableReturnValue = {
|
||||
}
|
||||
/**
|
||||
* Disable the BluetoothEmulation domain.
|
||||
*/
|
||||
export type disableParameters = {
|
||||
}
|
||||
export type disableReturnValue = {
|
||||
}
|
||||
/**
|
||||
* Simulates a peripheral with |address|, |name| and |knownServiceUuids|
|
||||
that has already been connected to the system.
|
||||
*/
|
||||
export type simulatePreconnectedPeripheralParameters = {
|
||||
address: string;
|
||||
name: string;
|
||||
manufacturerData: ManufacturerData[];
|
||||
knownServiceUuids: string[];
|
||||
}
|
||||
export type simulatePreconnectedPeripheralReturnValue = {
|
||||
}
|
||||
/**
|
||||
* Simulates an advertisement packet described in |entry| being received by
|
||||
the central.
|
||||
*/
|
||||
export type simulateAdvertisementParameters = {
|
||||
entry: ScanEntry;
|
||||
}
|
||||
export type simulateAdvertisementReturnValue = {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This domain is deprecated - use Runtime or Log instead.
|
||||
*/
|
||||
|
|
@ -20122,6 +20304,10 @@ Error was thrown.
|
|||
"Audits.checkContrast": Audits.checkContrastParameters;
|
||||
"Audits.checkFormsIssues": Audits.checkFormsIssuesParameters;
|
||||
"Extensions.loadUnpacked": Extensions.loadUnpackedParameters;
|
||||
"Extensions.getStorageItems": Extensions.getStorageItemsParameters;
|
||||
"Extensions.removeStorageItems": Extensions.removeStorageItemsParameters;
|
||||
"Extensions.clearStorageItems": Extensions.clearStorageItemsParameters;
|
||||
"Extensions.setStorageItems": Extensions.setStorageItemsParameters;
|
||||
"Autofill.trigger": Autofill.triggerParameters;
|
||||
"Autofill.setAddresses": Autofill.setAddressesParameters;
|
||||
"Autofill.disable": Autofill.disableParameters;
|
||||
|
|
@ -20232,6 +20418,7 @@ Error was thrown.
|
|||
"DOM.setNodeStackTracesEnabled": DOM.setNodeStackTracesEnabledParameters;
|
||||
"DOM.getNodeStackTraces": DOM.getNodeStackTracesParameters;
|
||||
"DOM.getFileInfo": DOM.getFileInfoParameters;
|
||||
"DOM.getDetachedDomNodes": DOM.getDetachedDomNodesParameters;
|
||||
"DOM.setInspectedNode": DOM.setInspectedNodeParameters;
|
||||
"DOM.setNodeName": DOM.setNodeNameParameters;
|
||||
"DOM.setNodeValue": DOM.setNodeValueParameters;
|
||||
|
|
@ -20616,6 +20803,10 @@ Error was thrown.
|
|||
"PWA.launchFilesInApp": PWA.launchFilesInAppParameters;
|
||||
"PWA.openCurrentPageInApp": PWA.openCurrentPageInAppParameters;
|
||||
"PWA.changeAppUserSettings": PWA.changeAppUserSettingsParameters;
|
||||
"BluetoothEmulation.enable": BluetoothEmulation.enableParameters;
|
||||
"BluetoothEmulation.disable": BluetoothEmulation.disableParameters;
|
||||
"BluetoothEmulation.simulatePreconnectedPeripheral": BluetoothEmulation.simulatePreconnectedPeripheralParameters;
|
||||
"BluetoothEmulation.simulateAdvertisement": BluetoothEmulation.simulateAdvertisementParameters;
|
||||
"Console.clearMessages": Console.clearMessagesParameters;
|
||||
"Console.disable": Console.disableParameters;
|
||||
"Console.enable": Console.enableParameters;
|
||||
|
|
@ -20722,6 +20913,10 @@ Error was thrown.
|
|||
"Audits.checkContrast": Audits.checkContrastReturnValue;
|
||||
"Audits.checkFormsIssues": Audits.checkFormsIssuesReturnValue;
|
||||
"Extensions.loadUnpacked": Extensions.loadUnpackedReturnValue;
|
||||
"Extensions.getStorageItems": Extensions.getStorageItemsReturnValue;
|
||||
"Extensions.removeStorageItems": Extensions.removeStorageItemsReturnValue;
|
||||
"Extensions.clearStorageItems": Extensions.clearStorageItemsReturnValue;
|
||||
"Extensions.setStorageItems": Extensions.setStorageItemsReturnValue;
|
||||
"Autofill.trigger": Autofill.triggerReturnValue;
|
||||
"Autofill.setAddresses": Autofill.setAddressesReturnValue;
|
||||
"Autofill.disable": Autofill.disableReturnValue;
|
||||
|
|
@ -20832,6 +21027,7 @@ Error was thrown.
|
|||
"DOM.setNodeStackTracesEnabled": DOM.setNodeStackTracesEnabledReturnValue;
|
||||
"DOM.getNodeStackTraces": DOM.getNodeStackTracesReturnValue;
|
||||
"DOM.getFileInfo": DOM.getFileInfoReturnValue;
|
||||
"DOM.getDetachedDomNodes": DOM.getDetachedDomNodesReturnValue;
|
||||
"DOM.setInspectedNode": DOM.setInspectedNodeReturnValue;
|
||||
"DOM.setNodeName": DOM.setNodeNameReturnValue;
|
||||
"DOM.setNodeValue": DOM.setNodeValueReturnValue;
|
||||
|
|
@ -21216,6 +21412,10 @@ Error was thrown.
|
|||
"PWA.launchFilesInApp": PWA.launchFilesInAppReturnValue;
|
||||
"PWA.openCurrentPageInApp": PWA.openCurrentPageInAppReturnValue;
|
||||
"PWA.changeAppUserSettings": PWA.changeAppUserSettingsReturnValue;
|
||||
"BluetoothEmulation.enable": BluetoothEmulation.enableReturnValue;
|
||||
"BluetoothEmulation.disable": BluetoothEmulation.disableReturnValue;
|
||||
"BluetoothEmulation.simulatePreconnectedPeripheral": BluetoothEmulation.simulatePreconnectedPeripheralReturnValue;
|
||||
"BluetoothEmulation.simulateAdvertisement": BluetoothEmulation.simulateAdvertisementReturnValue;
|
||||
"Console.clearMessages": Console.clearMessagesReturnValue;
|
||||
"Console.disable": Console.disableReturnValue;
|
||||
"Console.enable": Console.enableReturnValue;
|
||||
|
|
|
|||
|
|
@ -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/128.0.6613.36 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.22 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/128.0.6613.36 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.22 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/128.0.6613.36 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 7.0; SM-G950U Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.22 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/128.0.6613.36 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 7.0; SM-G950U Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.22 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/128.0.6613.36 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G965U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.22 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/128.0.6613.36 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G965U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.22 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/128.0.6613.36 Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.1.0; SM-T837A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.22 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/128.0.6613.36 Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.1.0; SM-T837A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.22 Safari/537.36",
|
||||
"viewport": {
|
||||
"width": 1138,
|
||||
"height": 712
|
||||
|
|
@ -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/128.0.6613.36 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/129.0.6668.22 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/128.0.6613.36 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/129.0.6668.22 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/128.0.6613.36 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/129.0.6668.22 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/128.0.6613.36 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/129.0.6668.22 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/128.0.6613.36 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/129.0.6668.22 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/128.0.6613.36 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/129.0.6668.22 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/128.0.6613.36 Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 10 Build/MOB31T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.22 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/128.0.6613.36 Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 10 Build/MOB31T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.22 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/128.0.6613.36 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.22 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/128.0.6613.36 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.22 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/128.0.6613.36 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.22 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/128.0.6613.36 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.22 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/128.0.6613.36 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/129.0.6668.22 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/128.0.6613.36 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/129.0.6668.22 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/128.0.6613.36 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6 Build/N6F26U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.22 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/128.0.6613.36 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6 Build/N6F26U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.22 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/128.0.6613.36 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/129.0.6668.22 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/128.0.6613.36 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/129.0.6668.22 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/128.0.6613.36 Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 7 Build/MOB30X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.22 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/128.0.6613.36 Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 7 Build/MOB30X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.22 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/128.0.6613.36 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/129.0.6668.22 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/128.0.6613.36 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/129.0.6668.22 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/128.0.6613.36 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/129.0.6668.22 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/128.0.6613.36 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/129.0.6668.22 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/128.0.6613.36 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/129.0.6668.22 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/128.0.6613.36 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/129.0.6668.22 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/128.0.6613.36 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 10; Pixel 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.22 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/128.0.6613.36 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 10; Pixel 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.22 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/128.0.6613.36 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 4a (5G)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.22 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/128.0.6613.36 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 4a (5G)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.22 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/128.0.6613.36 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.22 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/128.0.6613.36 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.22 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/128.0.6613.36 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 14; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.22 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/128.0.6613.36 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 14; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.22 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/128.0.6613.36 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.22 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/128.0.6613.36 Mobile Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.22 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/128.0.6613.36 Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.22 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/128.0.6613.36 Safari/537.36 Edg/128.0.6613.36",
|
||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.22 Safari/537.36 Edg/129.0.6668.22",
|
||||
"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/128.0.6613.36 Safari/537.36",
|
||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.22 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/128.0.6613.36 Safari/537.36 Edg/128.0.6613.36",
|
||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.22 Safari/537.36 Edg/129.0.6668.22",
|
||||
"screen": {
|
||||
"width": 1920,
|
||||
"height": 1080
|
||||
|
|
|
|||
|
|
@ -34,7 +34,8 @@ import { kLayoutSelectorNames, type LayoutSelectorName, layoutSelectorScore } fr
|
|||
import { asLocator } from '../../utils/isomorphic/locatorGenerators';
|
||||
import type { Language } from '../../utils/isomorphic/locatorGenerators';
|
||||
import { cacheNormalizedWhitespaces, escapeHTML, escapeHTMLAttribute, normalizeWhiteSpace, trimStringWithEllipsis } from '../../utils/isomorphic/stringUtils';
|
||||
import { generateSimpleDom, generateSimpleDomNode, selectorForSimpleDomNodeId } from './simpleDom';
|
||||
import { selectorForSimpleDomNodeId, generateSimpleDomNode } from './simpleDom';
|
||||
import type { SimpleDomNode } from './simpleDom';
|
||||
|
||||
export type FrameExpectParams = Omit<channels.FrameExpectParams, 'expectedValue'> & { expectedValue?: any };
|
||||
|
||||
|
|
@ -79,15 +80,12 @@ export class InjectedScript {
|
|||
endAriaCaches,
|
||||
escapeHTML,
|
||||
escapeHTMLAttribute,
|
||||
generateSimpleDom: generateSimpleDom.bind(undefined, this),
|
||||
generateSimpleDomNode: generateSimpleDomNode.bind(undefined, this),
|
||||
getAriaRole,
|
||||
getElementAccessibleDescription,
|
||||
getElementAccessibleName,
|
||||
isElementVisible,
|
||||
isInsideScope,
|
||||
normalizeWhiteSpace,
|
||||
selectorForSimpleDomNodeId: selectorForSimpleDomNodeId.bind(undefined, this),
|
||||
};
|
||||
|
||||
// eslint-disable-next-line no-restricted-globals
|
||||
|
|
@ -1314,6 +1312,17 @@ export class InjectedScript {
|
|||
}
|
||||
throw this.createStacklessError('Unknown expect matcher: ' + expression);
|
||||
}
|
||||
|
||||
generateSimpleDomNode(selector: string): SimpleDomNode | undefined {
|
||||
const element = this.querySelector(this.parseSelector(selector), this.document.documentElement, true);
|
||||
if (!element)
|
||||
return;
|
||||
return generateSimpleDomNode(this, element);
|
||||
}
|
||||
|
||||
selectorForSimpleDomNodeId(nodeId: string) {
|
||||
return selectorForSimpleDomNodeId(this, nodeId);
|
||||
}
|
||||
}
|
||||
|
||||
const autoClosingTags = new Set(['AREA', 'BASE', 'BR', 'COL', 'COMMAND', 'EMBED', 'HR', 'IMG', 'INPUT', 'KEYGEN', 'LINK', 'MENUITEM', 'META', 'PARAM', 'SOURCE', 'TRACK', 'WBR']);
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ import clipPaths from './clipPaths';
|
|||
import type { SimpleDomNode } from '../simpleDom';
|
||||
|
||||
interface RecorderDelegate {
|
||||
performAction?(action: actions.PerformOnRecordAction, simpleDomNode?: SimpleDomNode): Promise<void>;
|
||||
recordAction?(action: actions.Action, simpleDomNode?: SimpleDomNode): Promise<void>;
|
||||
performAction?(action: actions.PerformOnRecordAction): Promise<void>;
|
||||
recordAction?(action: actions.Action): Promise<void>;
|
||||
setSelector?(selector: string): Promise<void>;
|
||||
setMode?(mode: Mode): Promise<void>;
|
||||
setOverlayState?(state: OverlayState): Promise<void>;
|
||||
|
|
@ -931,7 +931,6 @@ export class Recorder {
|
|||
testIdAttributeName: 'data-testid',
|
||||
language: 'javascript',
|
||||
overlay: { offsetX: 0 },
|
||||
generateSimpleDom: false,
|
||||
};
|
||||
readonly document: Document;
|
||||
private _delegate: RecorderDelegate = {};
|
||||
|
|
@ -1186,13 +1185,11 @@ export class Recorder {
|
|||
}
|
||||
|
||||
async performAction(action: actions.PerformOnRecordAction) {
|
||||
const simpleDomNode = this._generateSimpleDomNode(action);
|
||||
await this._delegate.performAction?.(action, simpleDomNode).catch(() => {});
|
||||
await this._delegate.performAction?.(action).catch(() => {});
|
||||
}
|
||||
|
||||
recordAction(action: actions.Action) {
|
||||
const simpleDomNode = this._generateSimpleDomNode(action);
|
||||
void this._delegate.recordAction?.(action, simpleDomNode);
|
||||
void this._delegate.recordAction?.(action);
|
||||
}
|
||||
|
||||
setOverlayState(state: { offsetX: number; }) {
|
||||
|
|
@ -1202,18 +1199,6 @@ export class Recorder {
|
|||
setSelector(selector: string) {
|
||||
void this._delegate.setSelector?.(selector);
|
||||
}
|
||||
|
||||
private _generateSimpleDomNode(action: actions.Action): SimpleDomNode | undefined {
|
||||
if (!this.state.generateSimpleDom)
|
||||
return;
|
||||
if (!('selector' in action))
|
||||
return;
|
||||
|
||||
const element = this.injectedScript.querySelector(this.injectedScript.parseSelector(action.selector), this.document.documentElement, true);
|
||||
if (!element)
|
||||
return;
|
||||
return this.injectedScript.utils.generateSimpleDomNode(element);
|
||||
}
|
||||
}
|
||||
|
||||
class Dialog {
|
||||
|
|
|
|||
|
|
@ -77,10 +77,11 @@ function generate(injectedScript: InjectedScript, target?: Element): { dom: Simp
|
|||
const name = injectedScript.utils.getElementAccessibleName(element, false);
|
||||
const structuralId = String(++lastId);
|
||||
elements.set(structuralId, element);
|
||||
const tag = renderTag(injectedScript, role, name, structuralId, { value });
|
||||
if (element === target)
|
||||
resultTarget = { tag, id: structuralId };
|
||||
tokens.push(tag);
|
||||
tokens.push(renderTag(injectedScript, role, name, structuralId, { value }));
|
||||
if (element === target) {
|
||||
const tagNoValue = renderTag(injectedScript, role, name, structuralId);
|
||||
resultTarget = { tag: tagNoValue, id: structuralId };
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ export class Recorder implements InstrumentationListener {
|
|||
|
||||
constructor(context: BrowserContext, params: channels.BrowserContextRecorderSupplementEnableParams) {
|
||||
this._mode = params.mode || 'none';
|
||||
this._contextRecorder = new ContextRecorder(context, params);
|
||||
this._contextRecorder = new ContextRecorder(context, params, {});
|
||||
this._context = context;
|
||||
this._omitCallTracking = !!params.omitCallTracking;
|
||||
this._debugger = context.debugger();
|
||||
|
|
@ -160,7 +160,6 @@ export class Recorder implements InstrumentationListener {
|
|||
language: this._currentLanguage,
|
||||
testIdAttributeName: this._contextRecorder.testIdAttributeName(),
|
||||
overlay: this._overlayState,
|
||||
generateSimpleDom: false,
|
||||
};
|
||||
return uiState;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ import type { ActionInContext, FrameDescription, LanguageGeneratorOptions, Langu
|
|||
import { languageSet } from '../codegen/languages';
|
||||
import type { Dialog } from '../dialog';
|
||||
import { Frame } from '../frames';
|
||||
import type { SimpleDomNode } from '../injected/simpleDom';
|
||||
import { Page } from '../page';
|
||||
import type * as actions from './recorderActions';
|
||||
import { performAction } from './recorderRunner';
|
||||
|
|
@ -35,6 +34,10 @@ import { generateCode } from '../codegen/language';
|
|||
|
||||
type BindingSource = { frame: Frame, page: Page };
|
||||
|
||||
export interface ContextRecorderDelegate {
|
||||
rewriteActionInContext?(pageAliases: Map<Page, string>, actionInContext: ActionInContext): Promise<void>;
|
||||
}
|
||||
|
||||
export class ContextRecorder extends EventEmitter {
|
||||
static Events = {
|
||||
Change: 'change'
|
||||
|
|
@ -48,15 +51,17 @@ export class ContextRecorder extends EventEmitter {
|
|||
private _timers = new Set<NodeJS.Timeout>();
|
||||
private _context: BrowserContext;
|
||||
private _params: channels.BrowserContextRecorderSupplementEnableParams;
|
||||
private _delegate: ContextRecorderDelegate;
|
||||
private _recorderSources: Source[];
|
||||
private _throttledOutputFile: ThrottledFile | null = null;
|
||||
private _orderedLanguages: LanguageGenerator[] = [];
|
||||
private _listeners: RegisteredListener[] = [];
|
||||
|
||||
constructor(context: BrowserContext, params: channels.BrowserContextRecorderSupplementEnableParams) {
|
||||
constructor(context: BrowserContext, params: channels.BrowserContextRecorderSupplementEnableParams, delegate: ContextRecorderDelegate) {
|
||||
super();
|
||||
this._context = context;
|
||||
this._params = params;
|
||||
this._delegate = delegate;
|
||||
this._recorderSources = [];
|
||||
const language = params.language || context.attribution.playwright.options.sdkLanguage;
|
||||
this.setOutput(language, params.outputFile);
|
||||
|
|
@ -134,11 +139,11 @@ export class ContextRecorder extends EventEmitter {
|
|||
// Input actions that potentially lead to navigation are intercepted on the page and are
|
||||
// performed by the Playwright.
|
||||
await this._context.exposeBinding('__pw_recorderPerformAction', false,
|
||||
(source: BindingSource, action: actions.PerformOnRecordAction, simpleDomNode?: SimpleDomNode) => this._performAction(source.frame, action, simpleDomNode));
|
||||
(source: BindingSource, action: actions.PerformOnRecordAction) => this._performAction(source.frame, action));
|
||||
|
||||
// Other non-essential actions are simply being recorded.
|
||||
await this._context.exposeBinding('__pw_recorderRecordAction', false,
|
||||
(source: BindingSource, action: actions.Action, simpleDomNode?: SimpleDomNode) => this._recordAction(source.frame, action, simpleDomNode));
|
||||
(source: BindingSource, action: actions.Action) => this._recordAction(source.frame, action));
|
||||
|
||||
await this._context.extendInjectedScript(recorderSource.source);
|
||||
}
|
||||
|
|
@ -218,7 +223,7 @@ export class ContextRecorder extends EventEmitter {
|
|||
return this._params.testIdAttributeName || this._context.selectors().testIdAttributeName() || 'data-testid';
|
||||
}
|
||||
|
||||
private async _performAction(frame: Frame, action: actions.PerformOnRecordAction, simpleDomNode?: SimpleDomNode) {
|
||||
private async _performAction(frame: Frame, action: actions.PerformOnRecordAction) {
|
||||
// Commit last action so that no further signals are added to it.
|
||||
this._collection.commitLastAction();
|
||||
|
||||
|
|
@ -226,9 +231,11 @@ export class ContextRecorder extends EventEmitter {
|
|||
const actionInContext: ActionInContext = {
|
||||
frame: frameDescription,
|
||||
action,
|
||||
description: undefined, // TODO: generate description based on simple dom node.
|
||||
description: undefined,
|
||||
};
|
||||
|
||||
await this._delegate.rewriteActionInContext?.(this._pageAliases, actionInContext);
|
||||
|
||||
this._collection.willPerformAction(actionInContext);
|
||||
const success = await performAction(this._pageAliases, actionInContext);
|
||||
if (success) {
|
||||
|
|
@ -239,7 +246,7 @@ export class ContextRecorder extends EventEmitter {
|
|||
}
|
||||
}
|
||||
|
||||
private async _recordAction(frame: Frame, action: actions.Action, simpleDomNode?: SimpleDomNode) {
|
||||
private async _recordAction(frame: Frame, action: actions.Action) {
|
||||
// Commit last action so that no further signals are added to it.
|
||||
this._collection.commitLastAction();
|
||||
|
||||
|
|
@ -247,8 +254,11 @@ export class ContextRecorder extends EventEmitter {
|
|||
const actionInContext: ActionInContext = {
|
||||
frame: frameDescription,
|
||||
action,
|
||||
description: undefined, // TODO: generate description based on simple dom node.
|
||||
description: undefined,
|
||||
};
|
||||
|
||||
await this._delegate.rewriteActionInContext?.(this._pageAliases, actionInContext);
|
||||
|
||||
this._setCommittedAfterTimeout(actionInContext);
|
||||
this._collection.addAction(actionInContext);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,10 @@
|
|||
|
||||
import type { CallMetadata } from '../instrumentation';
|
||||
import type { CallLog, CallLogStatus } from '@recorder/recorderTypes';
|
||||
import type { Page } from '../page';
|
||||
import type { ActionInContext } from '../codegen/types';
|
||||
import type { Frame } from '../frames';
|
||||
import type * as actions from './recorderActions';
|
||||
|
||||
export function metadataToCallLog(metadata: CallMetadata, status: CallLogStatus): CallLog {
|
||||
let title = metadata.apiName || metadata.method;
|
||||
|
|
@ -48,3 +52,23 @@ export function metadataToCallLog(metadata: CallMetadata, status: CallLogStatus)
|
|||
export function buildFullSelector(framePath: string[], selector: string) {
|
||||
return [...framePath, selector].join(' >> internal:control=enter-frame >> ');
|
||||
}
|
||||
|
||||
export function mainFrameForAction(pageAliases: Map<Page, string>, actionInContext: ActionInContext): Frame {
|
||||
const pageAlias = actionInContext.frame.pageAlias;
|
||||
const page = [...pageAliases.entries()].find(([, alias]) => pageAlias === alias)?.[0];
|
||||
if (!page)
|
||||
throw new Error('Internal error: page not found');
|
||||
return page.mainFrame();
|
||||
}
|
||||
|
||||
export async function frameForAction(pageAliases: Map<Page, string>, actionInContext: ActionInContext, action: actions.ActionWithSelector): Promise<Frame> {
|
||||
const pageAlias = actionInContext.frame.pageAlias;
|
||||
const page = [...pageAliases.entries()].find(([, alias]) => pageAlias === alias)?.[0];
|
||||
if (!page)
|
||||
throw new Error('Internal error: page not found');
|
||||
const fullSelector = buildFullSelector(actionInContext.frame.framePath, action.selector);
|
||||
const result = await page.mainFrame().selectors.resolveFrameForSelector(fullSelector);
|
||||
if (!result)
|
||||
throw new Error('Internal error: frame not found');
|
||||
return result.frame;
|
||||
}
|
||||
|
|
|
|||
244
packages/playwright-core/types/protocol.d.ts
vendored
244
packages/playwright-core/types/protocol.d.ts
vendored
|
|
@ -1131,17 +1131,21 @@ using Audits.issueAdded event.
|
|||
}
|
||||
|
||||
/**
|
||||
* Defines commands and events for browser extensions. Available if the client
|
||||
is connected using the --remote-debugging-pipe flag and
|
||||
the --enable-unsafe-extension-debugging flag is set.
|
||||
* Defines commands and events for browser extensions.
|
||||
*/
|
||||
export module Extensions {
|
||||
/**
|
||||
* Storage areas.
|
||||
*/
|
||||
export type StorageArea = "session"|"local"|"sync"|"managed";
|
||||
|
||||
|
||||
/**
|
||||
* Installs an unpacked extension from the filesystem similar to
|
||||
--load-extension CLI flags. Returns extension ID once the extension
|
||||
has been installed.
|
||||
has been installed. Available if the client is connected using the
|
||||
--remote-debugging-pipe flag and the --enable-unsafe-extension-debugging
|
||||
flag is set.
|
||||
*/
|
||||
export type loadUnpackedParameters = {
|
||||
/**
|
||||
|
|
@ -1155,6 +1159,81 @@ has been installed.
|
|||
*/
|
||||
id: string;
|
||||
}
|
||||
/**
|
||||
* Gets data from extension storage in the given `storageArea`. If `keys` is
|
||||
specified, these are used to filter the result.
|
||||
*/
|
||||
export type getStorageItemsParameters = {
|
||||
/**
|
||||
* ID of extension.
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* StorageArea to retrieve data from.
|
||||
*/
|
||||
storageArea: StorageArea;
|
||||
/**
|
||||
* Keys to retrieve.
|
||||
*/
|
||||
keys?: string[];
|
||||
}
|
||||
export type getStorageItemsReturnValue = {
|
||||
data: { [key: string]: string };
|
||||
}
|
||||
/**
|
||||
* Removes `keys` from extension storage in the given `storageArea`.
|
||||
*/
|
||||
export type removeStorageItemsParameters = {
|
||||
/**
|
||||
* ID of extension.
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* StorageArea to remove data from.
|
||||
*/
|
||||
storageArea: StorageArea;
|
||||
/**
|
||||
* Keys to remove.
|
||||
*/
|
||||
keys: string[];
|
||||
}
|
||||
export type removeStorageItemsReturnValue = {
|
||||
}
|
||||
/**
|
||||
* Clears extension storage in the given `storageArea`.
|
||||
*/
|
||||
export type clearStorageItemsParameters = {
|
||||
/**
|
||||
* ID of extension.
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* StorageArea to remove data from.
|
||||
*/
|
||||
storageArea: StorageArea;
|
||||
}
|
||||
export type clearStorageItemsReturnValue = {
|
||||
}
|
||||
/**
|
||||
* Sets `values` in extension storage in the given `storageArea`. The provided `values`
|
||||
will be merged with existing values in the storage area.
|
||||
*/
|
||||
export type setStorageItemsParameters = {
|
||||
/**
|
||||
* ID of extension.
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* StorageArea to set data in.
|
||||
*/
|
||||
storageArea: StorageArea;
|
||||
/**
|
||||
* Values to set.
|
||||
*/
|
||||
values: { [key: string]: string };
|
||||
}
|
||||
export type setStorageItemsReturnValue = {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2532,16 +2611,6 @@ stylesheet rules) this rule came from.
|
|||
*/
|
||||
style: CSSStyle;
|
||||
}
|
||||
/**
|
||||
* CSS position-fallback rule representation.
|
||||
*/
|
||||
export interface CSSPositionFallbackRule {
|
||||
name: Value;
|
||||
/**
|
||||
* List of keyframes.
|
||||
*/
|
||||
tryRules: CSSTryRule[];
|
||||
}
|
||||
/**
|
||||
* CSS @position-try rule representation.
|
||||
*/
|
||||
|
|
@ -2888,10 +2957,6 @@ attributes) for a DOM node identified by `nodeId`.
|
|||
* A list of CSS keyframed animations matching this node.
|
||||
*/
|
||||
cssKeyframesRules?: CSSKeyframesRule[];
|
||||
/**
|
||||
* A list of CSS position fallbacks matching this node.
|
||||
*/
|
||||
cssPositionFallbackRules?: CSSPositionFallbackRule[];
|
||||
/**
|
||||
* A list of CSS @position-try rules matching this node, based on the position-try-fallbacks property.
|
||||
*/
|
||||
|
|
@ -3496,7 +3561,7 @@ front-end.
|
|||
/**
|
||||
* Pseudo element type.
|
||||
*/
|
||||
export type PseudoType = "first-line"|"first-letter"|"before"|"after"|"marker"|"backdrop"|"selection"|"search-text"|"target-text"|"spelling-error"|"grammar-error"|"highlight"|"first-line-inherited"|"scroll-marker"|"scroll-marker-group"|"scrollbar"|"scrollbar-thumb"|"scrollbar-button"|"scrollbar-track"|"scrollbar-track-piece"|"scrollbar-corner"|"resizer"|"input-list-button"|"view-transition"|"view-transition-group"|"view-transition-image-pair"|"view-transition-old"|"view-transition-new";
|
||||
export type PseudoType = "first-line"|"first-letter"|"before"|"after"|"marker"|"backdrop"|"selection"|"search-text"|"target-text"|"spelling-error"|"grammar-error"|"highlight"|"first-line-inherited"|"scroll-marker"|"scroll-marker-group"|"scroll-next-button"|"scroll-prev-button"|"scrollbar"|"scrollbar-thumb"|"scrollbar-button"|"scrollbar-track"|"scrollbar-track-piece"|"scrollbar-corner"|"resizer"|"input-list-button"|"view-transition"|"view-transition-group"|"view-transition-image-pair"|"view-transition-old"|"view-transition-new";
|
||||
/**
|
||||
* Shadow root type.
|
||||
*/
|
||||
|
|
@ -3646,6 +3711,13 @@ The property is always undefined now.
|
|||
compatibilityMode?: CompatibilityMode;
|
||||
assignedSlot?: BackendNode;
|
||||
}
|
||||
/**
|
||||
* A structure to hold the top-level node of a detached tree and an array of its retained descendants.
|
||||
*/
|
||||
export interface DetachedElementInfo {
|
||||
treeNode: Node;
|
||||
retainedNodeIds: NodeId[];
|
||||
}
|
||||
/**
|
||||
* A structure holding an RGBA color.
|
||||
*/
|
||||
|
|
@ -4693,6 +4765,17 @@ File wrapper.
|
|||
export type getFileInfoReturnValue = {
|
||||
path: string;
|
||||
}
|
||||
/**
|
||||
* Returns list of detached nodes
|
||||
*/
|
||||
export type getDetachedDomNodesParameters = {
|
||||
}
|
||||
export type getDetachedDomNodesReturnValue = {
|
||||
/**
|
||||
* The list of detached nodes
|
||||
*/
|
||||
detachedNodes: DetachedElementInfo[];
|
||||
}
|
||||
/**
|
||||
* Enables console to refer to the node with given id via $x (see Command Line API for more details
|
||||
$x functions).
|
||||
|
|
@ -11369,7 +11452,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"|"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";
|
||||
export type PermissionsPolicyFeature = "accelerometer"|"all-screens-capture"|"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"|"media-playback-while-not-visible"|"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.
|
||||
*/
|
||||
|
|
@ -11784,7 +11867,7 @@ Example URLs: http://www.google.com/file.html -> "google.com"
|
|||
*/
|
||||
fixed?: number;
|
||||
}
|
||||
export type ClientNavigationReason = "formSubmissionGet"|"formSubmissionPost"|"httpHeaderRefresh"|"scriptInitiated"|"metaTagRefresh"|"pageBlockInterstitial"|"reload"|"anchorClick";
|
||||
export type ClientNavigationReason = "anchorClick"|"formSubmissionGet"|"formSubmissionPost"|"httpHeaderRefresh"|"initialFrameNavigation"|"metaTagRefresh"|"other"|"pageBlockInterstitial"|"reload"|"scriptInitiated";
|
||||
export type ClientNavigationDisposition = "currentTab"|"newTab"|"newWindow"|"download";
|
||||
export interface InstallabilityErrorArgument {
|
||||
/**
|
||||
|
|
@ -12298,6 +12381,10 @@ when bfcache navigation fails.
|
|||
* Frame's new url.
|
||||
*/
|
||||
url: string;
|
||||
/**
|
||||
* Navigation type
|
||||
*/
|
||||
navigationType: "fragment"|"historyApi"|"other";
|
||||
}
|
||||
/**
|
||||
* Compressed image data requested by the `startScreencast`.
|
||||
|
|
@ -16922,7 +17009,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"|"WindowClosed";
|
||||
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"|"SlowNetwork"|"OtherPrerenderedPageActivated";
|
||||
/**
|
||||
* Preloading status values, see also PreloadingTriggeringOutcome. This
|
||||
status is shared by prefetchStatusUpdated and prerenderStatusUpdated.
|
||||
|
|
@ -17270,6 +17357,101 @@ supported yet.
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This domain allows configuring virtual Bluetooth devices to test
|
||||
the web-bluetooth API.
|
||||
*/
|
||||
export module BluetoothEmulation {
|
||||
/**
|
||||
* Indicates the various states of Central.
|
||||
*/
|
||||
export type CentralState = "absent"|"powered-off"|"powered-on";
|
||||
/**
|
||||
* Stores the manufacturer data
|
||||
*/
|
||||
export interface ManufacturerData {
|
||||
/**
|
||||
* Company identifier
|
||||
https://bitbucket.org/bluetooth-SIG/public/src/main/assigned_numbers/company_identifiers/company_identifiers.yaml
|
||||
https://usb.org/developers
|
||||
*/
|
||||
key: number;
|
||||
/**
|
||||
* Manufacturer-specific data
|
||||
*/
|
||||
data: binary;
|
||||
}
|
||||
/**
|
||||
* Stores the byte data of the advertisement packet sent by a Bluetooth device.
|
||||
*/
|
||||
export interface ScanRecord {
|
||||
name?: string;
|
||||
uuids?: string[];
|
||||
/**
|
||||
* Stores the external appearance description of the device.
|
||||
*/
|
||||
appearance?: number;
|
||||
/**
|
||||
* Stores the transmission power of a broadcasting device.
|
||||
*/
|
||||
txPower?: number;
|
||||
/**
|
||||
* Key is the company identifier and the value is an array of bytes of
|
||||
manufacturer specific data.
|
||||
*/
|
||||
manufacturerData?: ManufacturerData[];
|
||||
}
|
||||
/**
|
||||
* Stores the advertisement packet information that is sent by a Bluetooth device.
|
||||
*/
|
||||
export interface ScanEntry {
|
||||
deviceAddress: string;
|
||||
rssi: number;
|
||||
scanRecord: ScanRecord;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Enable the BluetoothEmulation domain.
|
||||
*/
|
||||
export type enableParameters = {
|
||||
/**
|
||||
* State of the simulated central.
|
||||
*/
|
||||
state: CentralState;
|
||||
}
|
||||
export type enableReturnValue = {
|
||||
}
|
||||
/**
|
||||
* Disable the BluetoothEmulation domain.
|
||||
*/
|
||||
export type disableParameters = {
|
||||
}
|
||||
export type disableReturnValue = {
|
||||
}
|
||||
/**
|
||||
* Simulates a peripheral with |address|, |name| and |knownServiceUuids|
|
||||
that has already been connected to the system.
|
||||
*/
|
||||
export type simulatePreconnectedPeripheralParameters = {
|
||||
address: string;
|
||||
name: string;
|
||||
manufacturerData: ManufacturerData[];
|
||||
knownServiceUuids: string[];
|
||||
}
|
||||
export type simulatePreconnectedPeripheralReturnValue = {
|
||||
}
|
||||
/**
|
||||
* Simulates an advertisement packet described in |entry| being received by
|
||||
the central.
|
||||
*/
|
||||
export type simulateAdvertisementParameters = {
|
||||
entry: ScanEntry;
|
||||
}
|
||||
export type simulateAdvertisementReturnValue = {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This domain is deprecated - use Runtime or Log instead.
|
||||
*/
|
||||
|
|
@ -20122,6 +20304,10 @@ Error was thrown.
|
|||
"Audits.checkContrast": Audits.checkContrastParameters;
|
||||
"Audits.checkFormsIssues": Audits.checkFormsIssuesParameters;
|
||||
"Extensions.loadUnpacked": Extensions.loadUnpackedParameters;
|
||||
"Extensions.getStorageItems": Extensions.getStorageItemsParameters;
|
||||
"Extensions.removeStorageItems": Extensions.removeStorageItemsParameters;
|
||||
"Extensions.clearStorageItems": Extensions.clearStorageItemsParameters;
|
||||
"Extensions.setStorageItems": Extensions.setStorageItemsParameters;
|
||||
"Autofill.trigger": Autofill.triggerParameters;
|
||||
"Autofill.setAddresses": Autofill.setAddressesParameters;
|
||||
"Autofill.disable": Autofill.disableParameters;
|
||||
|
|
@ -20232,6 +20418,7 @@ Error was thrown.
|
|||
"DOM.setNodeStackTracesEnabled": DOM.setNodeStackTracesEnabledParameters;
|
||||
"DOM.getNodeStackTraces": DOM.getNodeStackTracesParameters;
|
||||
"DOM.getFileInfo": DOM.getFileInfoParameters;
|
||||
"DOM.getDetachedDomNodes": DOM.getDetachedDomNodesParameters;
|
||||
"DOM.setInspectedNode": DOM.setInspectedNodeParameters;
|
||||
"DOM.setNodeName": DOM.setNodeNameParameters;
|
||||
"DOM.setNodeValue": DOM.setNodeValueParameters;
|
||||
|
|
@ -20616,6 +20803,10 @@ Error was thrown.
|
|||
"PWA.launchFilesInApp": PWA.launchFilesInAppParameters;
|
||||
"PWA.openCurrentPageInApp": PWA.openCurrentPageInAppParameters;
|
||||
"PWA.changeAppUserSettings": PWA.changeAppUserSettingsParameters;
|
||||
"BluetoothEmulation.enable": BluetoothEmulation.enableParameters;
|
||||
"BluetoothEmulation.disable": BluetoothEmulation.disableParameters;
|
||||
"BluetoothEmulation.simulatePreconnectedPeripheral": BluetoothEmulation.simulatePreconnectedPeripheralParameters;
|
||||
"BluetoothEmulation.simulateAdvertisement": BluetoothEmulation.simulateAdvertisementParameters;
|
||||
"Console.clearMessages": Console.clearMessagesParameters;
|
||||
"Console.disable": Console.disableParameters;
|
||||
"Console.enable": Console.enableParameters;
|
||||
|
|
@ -20722,6 +20913,10 @@ Error was thrown.
|
|||
"Audits.checkContrast": Audits.checkContrastReturnValue;
|
||||
"Audits.checkFormsIssues": Audits.checkFormsIssuesReturnValue;
|
||||
"Extensions.loadUnpacked": Extensions.loadUnpackedReturnValue;
|
||||
"Extensions.getStorageItems": Extensions.getStorageItemsReturnValue;
|
||||
"Extensions.removeStorageItems": Extensions.removeStorageItemsReturnValue;
|
||||
"Extensions.clearStorageItems": Extensions.clearStorageItemsReturnValue;
|
||||
"Extensions.setStorageItems": Extensions.setStorageItemsReturnValue;
|
||||
"Autofill.trigger": Autofill.triggerReturnValue;
|
||||
"Autofill.setAddresses": Autofill.setAddressesReturnValue;
|
||||
"Autofill.disable": Autofill.disableReturnValue;
|
||||
|
|
@ -20832,6 +21027,7 @@ Error was thrown.
|
|||
"DOM.setNodeStackTracesEnabled": DOM.setNodeStackTracesEnabledReturnValue;
|
||||
"DOM.getNodeStackTraces": DOM.getNodeStackTracesReturnValue;
|
||||
"DOM.getFileInfo": DOM.getFileInfoReturnValue;
|
||||
"DOM.getDetachedDomNodes": DOM.getDetachedDomNodesReturnValue;
|
||||
"DOM.setInspectedNode": DOM.setInspectedNodeReturnValue;
|
||||
"DOM.setNodeName": DOM.setNodeNameReturnValue;
|
||||
"DOM.setNodeValue": DOM.setNodeValueReturnValue;
|
||||
|
|
@ -21216,6 +21412,10 @@ Error was thrown.
|
|||
"PWA.launchFilesInApp": PWA.launchFilesInAppReturnValue;
|
||||
"PWA.openCurrentPageInApp": PWA.openCurrentPageInAppReturnValue;
|
||||
"PWA.changeAppUserSettings": PWA.changeAppUserSettingsReturnValue;
|
||||
"BluetoothEmulation.enable": BluetoothEmulation.enableReturnValue;
|
||||
"BluetoothEmulation.disable": BluetoothEmulation.disableReturnValue;
|
||||
"BluetoothEmulation.simulatePreconnectedPeripheral": BluetoothEmulation.simulatePreconnectedPeripheralReturnValue;
|
||||
"BluetoothEmulation.simulateAdvertisement": BluetoothEmulation.simulateAdvertisementReturnValue;
|
||||
"Console.clearMessages": Console.clearMessagesReturnValue;
|
||||
"Console.disable": Console.disableReturnValue;
|
||||
"Console.enable": Console.enableReturnValue;
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
"@sveltejs/vite-plugin-svelte": "^3.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"svelte": "^4.2.8"
|
||||
"svelte": "^4.2.19"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ export interface TestServerInterface {
|
|||
|
||||
installBrowsers(params: {}): Promise<void>;
|
||||
|
||||
runGlobalSetup(params: {}): Promise<{
|
||||
runGlobalSetup(params: { outputDir?: string }): Promise<{
|
||||
report: ReportEntry[],
|
||||
status: reporterTypes.FullResult['status']
|
||||
}>;
|
||||
|
|
@ -81,6 +81,7 @@ export interface TestServerInterface {
|
|||
locations?: string[];
|
||||
grep?: string;
|
||||
grepInvert?: string;
|
||||
outputDir?: string;
|
||||
}): Promise<{
|
||||
report: ReportEntry[],
|
||||
status: reporterTypes.FullResult['status']
|
||||
|
|
|
|||
|
|
@ -148,7 +148,10 @@ class TestServerDispatcher implements TestServerInterface {
|
|||
async runGlobalSetup(params: Parameters<TestServerInterface['runGlobalSetup']>[0]): ReturnType<TestServerInterface['runGlobalSetup']> {
|
||||
await this.runGlobalTeardown();
|
||||
|
||||
const { config, error } = await this._loadConfig();
|
||||
const overrides: ConfigCLIOverrides = {
|
||||
outputDir: params.outputDir,
|
||||
};
|
||||
const { config, error } = await this._loadConfig(overrides);
|
||||
if (!config) {
|
||||
const { reporter, report } = await this._collectingInternalReporter();
|
||||
// Produce dummy config when it has an error.
|
||||
|
|
@ -256,6 +259,7 @@ class TestServerDispatcher implements TestServerInterface {
|
|||
const overrides: ConfigCLIOverrides = {
|
||||
repeatEach: 1,
|
||||
retries: 0,
|
||||
outputDir: params.outputDir,
|
||||
};
|
||||
const { config, error } = await this._loadConfig(overrides);
|
||||
if (!config) {
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ export async function detectChangedTestFiles(baseCommit: string, configDir: stri
|
|||
|
||||
const unknownRevision = error.output.some(line => line?.includes('unknown revision'));
|
||||
if (unknownRevision) {
|
||||
const isShallowClone = childProcess.execSync('git rev-parse --is-shallow-repository', { encoding: 'utf-8', stdio: 'pipe' }).trim() === 'true';
|
||||
const isShallowClone = childProcess.execSync('git rev-parse --is-shallow-repository', { encoding: 'utf-8', stdio: 'pipe', cwd: configDir }).trim() === 'true';
|
||||
if (isShallowClone) {
|
||||
throw new Error([
|
||||
`The repository is a shallow clone and does not have '${baseCommit}' available locally.`,
|
||||
|
|
|
|||
18
packages/playwright/types/test.d.ts
vendored
18
packages/playwright/types/test.d.ts
vendored
|
|
@ -1825,8 +1825,10 @@ type TestDetailsAnnotation = {
|
|||
description?: string;
|
||||
};
|
||||
|
||||
type TestDetailsTag = `@${string}`;
|
||||
|
||||
export type TestDetails = {
|
||||
tag?: string | string[];
|
||||
tag?: TestDetailsTag | TestDetailsTag[];
|
||||
annotation?: TestDetailsAnnotation | TestDetailsAnnotation[];
|
||||
}
|
||||
|
||||
|
|
@ -6565,15 +6567,17 @@ type MakeMatchers<R, T, ExtendedMatchers> = {
|
|||
rejects: MakeMatchers<Promise<R>, any, ExtendedMatchers>;
|
||||
} & IfAny<T, AllMatchers<R, T>, SpecificMatchers<R, T> & ToUserMatcherObject<ExtendedMatchers, T>>;
|
||||
|
||||
type PollMatchers<R, T, ExtendedMatchers> = {
|
||||
/**
|
||||
* If you know how to test something, `.not` lets you test its opposite.
|
||||
*/
|
||||
not: PollMatchers<R, T, ExtendedMatchers>;
|
||||
} & BaseMatchers<R, T> & ToUserMatcherObject<ExtendedMatchers, T>;
|
||||
|
||||
export type Expect<ExtendedMatchers = {}> = {
|
||||
<T = unknown>(actual: T, messageOrOptions?: string | { message?: string }): MakeMatchers<void, T, ExtendedMatchers>;
|
||||
soft: <T = unknown>(actual: T, messageOrOptions?: string | { message?: string }) => MakeMatchers<void, T, ExtendedMatchers>;
|
||||
poll: <T = unknown>(actual: () => T | Promise<T>, messageOrOptions?: string | { message?: string, timeout?: number, intervals?: number[] }) => BaseMatchers<Promise<void>, T> & {
|
||||
/**
|
||||
* If you know how to test something, `.not` lets you test its opposite.
|
||||
*/
|
||||
not: BaseMatchers<Promise<void>, T>;
|
||||
};
|
||||
poll: <T = unknown>(actual: () => T | Promise<T>, messageOrOptions?: string | { message?: string, timeout?: number, intervals?: number[] }) => PollMatchers<Promise<void>,T, ExtendedMatchers>
|
||||
extend<MoreMatchers extends Record<string, (this: ExpectMatcherState, receiver: any, ...args: any[]) => MatcherReturnType | Promise<MatcherReturnType>>>(matchers: MoreMatchers): Expect<ExtendedMatchers & MoreMatchers>;
|
||||
configure: (configuration: {
|
||||
message?: string,
|
||||
|
|
|
|||
|
|
@ -51,7 +51,6 @@ export type UIState = {
|
|||
language: Language;
|
||||
testIdAttributeName: string;
|
||||
overlay: OverlayState;
|
||||
generateSimpleDom: boolean;
|
||||
};
|
||||
|
||||
export type CallLogStatus = 'in-progress' | 'done' | 'error' | 'paused';
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ const RequestTab: React.FunctionComponent<{
|
|||
React.useEffect(() => {
|
||||
const readResources = async () => {
|
||||
if (resource.request.postData) {
|
||||
const requestContentTypeHeader = resource.request.headers.find(q => q.name === 'Content-Type');
|
||||
const requestContentTypeHeader = resource.request.headers.find(q => q.name.toLowerCase() === 'content-type');
|
||||
const requestContentType = requestContentTypeHeader ? requestContentTypeHeader.value : '';
|
||||
if (resource.request.postData._sha1) {
|
||||
const response = await fetch(`sha1/${resource.request.postData._sha1}`);
|
||||
|
|
|
|||
|
|
@ -254,7 +254,6 @@ export const InspectModeController: React.FunctionComponent<{
|
|||
language: sdkLanguage,
|
||||
testIdAttributeName,
|
||||
overlay: { offsetX: 0 },
|
||||
generateSimpleDom: false,
|
||||
}, {
|
||||
async setSelector(selector: string) {
|
||||
setHighlightedLocator(asLocator(sdkLanguage, frameSelector + selector));
|
||||
|
|
|
|||
|
|
@ -205,12 +205,14 @@ export const UIModeView: React.FC<{}> = ({
|
|||
interceptStdio: true,
|
||||
watchTestDirs: true
|
||||
});
|
||||
const { status, report } = await testServerConnection.runGlobalSetup({});
|
||||
const { status, report } = await testServerConnection.runGlobalSetup({
|
||||
outputDir: queryParams.outputDir,
|
||||
});
|
||||
teleSuiteUpdater.processGlobalReport(report);
|
||||
if (status !== 'passed')
|
||||
return;
|
||||
|
||||
const result = await testServerConnection.listTests({ projects: queryParams.projects, locations: queryParams.args, grep: queryParams.grep, grepInvert: queryParams.grepInvert });
|
||||
const result = await testServerConnection.listTests({ projects: queryParams.projects, locations: queryParams.args, grep: queryParams.grep, grepInvert: queryParams.grepInvert, outputDir: queryParams.outputDir });
|
||||
teleSuiteUpdater.processListReport(result.report);
|
||||
|
||||
testServerConnection.onReport(params => {
|
||||
|
|
@ -333,7 +335,7 @@ export const UIModeView: React.FC<{}> = ({
|
|||
commandQueue.current = commandQueue.current.then(async () => {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const result = await testServerConnection.listTests({ projects: queryParams.projects, locations: queryParams.args, grep: queryParams.grep, grepInvert: queryParams.grepInvert });
|
||||
const result = await testServerConnection.listTests({ projects: queryParams.projects, locations: queryParams.args, grep: queryParams.grep, grepInvert: queryParams.grepInvert, outputDir: queryParams.outputDir });
|
||||
teleSuiteUpdater.processListReport(result.report);
|
||||
} catch (e) {
|
||||
// eslint-disable-next-line no-console
|
||||
|
|
|
|||
|
|
@ -13,6 +13,25 @@
|
|||
</style>
|
||||
<script src='script.js'></script>
|
||||
<script>fetch('/api/endpoint')</script>
|
||||
<script>
|
||||
const body = JSON.stringify({
|
||||
data: {
|
||||
key: 'value',
|
||||
array: ['value-1', 'value-2'],
|
||||
},
|
||||
});
|
||||
|
||||
fetch('/post-data-1', {
|
||||
method: 'POST',
|
||||
headers: { 'content-type': 'application/json' },
|
||||
body,
|
||||
});
|
||||
fetch('/post-data-2', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body,
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Network Tab Test</h1>
|
||||
|
|
|
|||
|
|
@ -44,7 +44,10 @@ test('should poll predicate', async ({ runInlineTest }) => {
|
|||
test('should compile', async ({ runTSC }) => {
|
||||
const result = await runTSC({
|
||||
'a.spec.ts': `
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { test, expect as baseExpect } from '@playwright/test';
|
||||
const expect = baseExpect.extend({
|
||||
toBeWithinRange() { return { message: () => "is within range", pass: true }; },
|
||||
})
|
||||
test('should poll sync predicate', async ({ page }) => {
|
||||
let i = 0;
|
||||
test.expect.poll(() => ++i).toBe(3);
|
||||
|
|
@ -57,6 +60,7 @@ test('should compile', async ({ runTSC }) => {
|
|||
return ++i;
|
||||
}).toBe(3);
|
||||
test.expect.poll(() => Promise.resolve(++i)).toBe(3);
|
||||
expect.poll(() => Promise.resolve(++i)).toBeWithinRange();
|
||||
|
||||
// @ts-expect-error
|
||||
await test.expect.poll(() => page.locator('foo')).toBeEnabled();
|
||||
|
|
|
|||
|
|
@ -802,6 +802,32 @@ for (const useIntermediateMergeReport of [false] as const) {
|
|||
await expect(page.locator('.attachment-body')).toHaveText(['foo', '{"foo":1}', 'utf16 encoded']);
|
||||
});
|
||||
|
||||
test('should have link for opening HTML attachments in new tab', async ({ runInlineTest, page, showReport }) => {
|
||||
const result = await runInlineTest({
|
||||
'a.test.js': `
|
||||
import { test, expect } from '@playwright/test';
|
||||
test('passing', async ({ page }, testInfo) => {
|
||||
testInfo.attach('axe-report.html', {
|
||||
contentType: 'text/html',
|
||||
body: '<h1>Axe Report</h1>',
|
||||
});
|
||||
});
|
||||
`,
|
||||
}, { reporter: 'dot,html' }, { PLAYWRIGHT_HTML_OPEN: 'never' });
|
||||
expect(result.exitCode).toBe(0);
|
||||
|
||||
await showReport();
|
||||
await page.getByText('passing', { exact: true }).click();
|
||||
|
||||
const [newTab] = await Promise.all([
|
||||
page.waitForEvent('popup'),
|
||||
page.getByText('axe-report.html', { exact: true }).click(),
|
||||
]);
|
||||
|
||||
await expect(newTab).toHaveURL(/^blob:/);
|
||||
await expect(newTab.getByText('Axe Report')).toBeVisible();
|
||||
});
|
||||
|
||||
test('should use file-browser friendly extensions for buffer attachments based on contentType', async ({ runInlineTest, showReport, page }, testInfo) => {
|
||||
const result = await runInlineTest({
|
||||
'a.test.js': `
|
||||
|
|
|
|||
|
|
@ -147,6 +147,18 @@ test('should enforce @ symbol', async ({ runInlineTest }) => {
|
|||
expect(result.output).toContain(`Error: Tag must start with "@" symbol, got "foo" instead.`);
|
||||
});
|
||||
|
||||
test('types should enforce @ symbol', async ({ runTSC }) => {
|
||||
const result = await runTSC({
|
||||
'stdio.spec.ts': `
|
||||
import { test, expect } from '@playwright/test';
|
||||
test('test1', { tag: 'foo' }, () => {
|
||||
});
|
||||
`
|
||||
});
|
||||
expect(result.exitCode).toBe(2);
|
||||
expect(result.output).toContain('error TS2322: Type \'"foo"\' is not assignable to type \'`@${string}` | `@${string}`[] | undefined');
|
||||
});
|
||||
|
||||
test('should be included in testInfo', async ({ runInlineTest }, testInfo) => {
|
||||
const result = await runInlineTest({
|
||||
'a.test.ts': `
|
||||
|
|
|
|||
|
|
@ -93,3 +93,45 @@ test('should filter network requests by url', async ({ runUITest, server }) => {
|
|||
await expect(networkItems).toHaveCount(1);
|
||||
await expect(networkItems.getByText('font.woff2')).toBeVisible();
|
||||
});
|
||||
|
||||
test('should format JSON request body', async ({ runUITest, server }) => {
|
||||
const { page } = await runUITest({
|
||||
'network-tab.test.ts': `
|
||||
import { test, expect } from '@playwright/test';
|
||||
test('network tab test', async ({ page }) => {
|
||||
await page.goto('${server.PREFIX}/network-tab/network.html');
|
||||
});
|
||||
`,
|
||||
});
|
||||
|
||||
await page.getByText('network tab test').dblclick();
|
||||
await page.getByText('Network', { exact: true }).click();
|
||||
|
||||
await page.getByText('post-data-1').click();
|
||||
|
||||
await expect(page.locator('.CodeMirror-code .CodeMirror-line').allInnerTexts()).resolves.toEqual([
|
||||
'{',
|
||||
' "data": {',
|
||||
' "key": "value",',
|
||||
' "array": [',
|
||||
' "value-1",',
|
||||
' "value-2"',
|
||||
' ]',
|
||||
' }',
|
||||
'}',
|
||||
]);
|
||||
|
||||
await page.getByText('post-data-2').click();
|
||||
|
||||
await expect(page.locator('.CodeMirror-code .CodeMirror-line').allInnerTexts()).resolves.toEqual([
|
||||
'{',
|
||||
' "data": {',
|
||||
' "key": "value",',
|
||||
' "array": [',
|
||||
' "value-1",',
|
||||
' "value-2"',
|
||||
' ]',
|
||||
' }',
|
||||
'}',
|
||||
]);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import path from 'path';
|
|||
|
||||
test.describe.configure({ mode: 'parallel', retries });
|
||||
|
||||
test('should run global setup and teardown', async ({ runUITest }) => {
|
||||
test('should run global setup and teardown', async ({ runUITest }, testInfo) => {
|
||||
const { page, testProcess } = await runUITest({
|
||||
'playwright.config.ts': `
|
||||
import { defineConfig } from '@playwright/test';
|
||||
|
|
@ -29,26 +29,36 @@ test('should run global setup and teardown', async ({ runUITest }) => {
|
|||
});
|
||||
`,
|
||||
'globalSetup.ts': `
|
||||
export default () => console.log('\\n%%from-global-setup');
|
||||
import { basename } from "node:path";
|
||||
export default (config) => {
|
||||
console.log('\\n%%from-global-setup');
|
||||
console.log("setupOutputDir: " + basename(config.projects[0].outputDir));
|
||||
};
|
||||
`,
|
||||
'globalTeardown.ts': `
|
||||
export default () => console.log('\\n%%from-global-teardown');
|
||||
export default (config) => {
|
||||
console.log('\\n%%from-global-teardown');
|
||||
console.log('%%' + JSON.stringify(config));
|
||||
};
|
||||
`,
|
||||
'a.test.js': `
|
||||
import { test, expect } from '@playwright/test';
|
||||
test('should work', async ({}) => {});
|
||||
`
|
||||
});
|
||||
}, undefined, { additionalArgs: ['--output=foo'] });
|
||||
await page.getByTitle('Run all').click();
|
||||
await expect(page.getByTestId('status-line')).toHaveText('1/1 passed (100%)');
|
||||
|
||||
await page.getByTitle('Toggle output').click();
|
||||
await expect(page.getByTestId('output')).toContainText('from-global-setup');
|
||||
const output = page.getByTestId('output');
|
||||
await expect(output).toContainText('from-global-setup');
|
||||
await expect(output).toContainText('setupOutputDir: foo');
|
||||
await page.close();
|
||||
|
||||
await expect.poll(() => testProcess.outputLines()).toEqual([
|
||||
'from-global-teardown',
|
||||
]);
|
||||
await expect.poll(() => testProcess.outputLines()).toContain('from-global-teardown');
|
||||
|
||||
const teardownConfig = JSON.parse(testProcess.outputLines()[1]);
|
||||
expect(teardownConfig.projects[0].outputDir).toEqual(testInfo.outputPath('foo'));
|
||||
});
|
||||
|
||||
test('should teardown on sigint', async ({ runUITest, nodeVersion }) => {
|
||||
|
|
|
|||
18
utils/generate_types/overrides-test.d.ts
vendored
18
utils/generate_types/overrides-test.d.ts
vendored
|
|
@ -70,8 +70,10 @@ type TestDetailsAnnotation = {
|
|||
description?: string;
|
||||
};
|
||||
|
||||
type TestDetailsTag = `@${string}`;
|
||||
|
||||
export type TestDetails = {
|
||||
tag?: string | string[];
|
||||
tag?: TestDetailsTag | TestDetailsTag[];
|
||||
annotation?: TestDetailsAnnotation | TestDetailsAnnotation[];
|
||||
}
|
||||
|
||||
|
|
@ -403,15 +405,17 @@ type MakeMatchers<R, T, ExtendedMatchers> = {
|
|||
rejects: MakeMatchers<Promise<R>, any, ExtendedMatchers>;
|
||||
} & IfAny<T, AllMatchers<R, T>, SpecificMatchers<R, T> & ToUserMatcherObject<ExtendedMatchers, T>>;
|
||||
|
||||
type PollMatchers<R, T, ExtendedMatchers> = {
|
||||
/**
|
||||
* If you know how to test something, `.not` lets you test its opposite.
|
||||
*/
|
||||
not: PollMatchers<R, T, ExtendedMatchers>;
|
||||
} & BaseMatchers<R, T> & ToUserMatcherObject<ExtendedMatchers, T>;
|
||||
|
||||
export type Expect<ExtendedMatchers = {}> = {
|
||||
<T = unknown>(actual: T, messageOrOptions?: string | { message?: string }): MakeMatchers<void, T, ExtendedMatchers>;
|
||||
soft: <T = unknown>(actual: T, messageOrOptions?: string | { message?: string }) => MakeMatchers<void, T, ExtendedMatchers>;
|
||||
poll: <T = unknown>(actual: () => T | Promise<T>, messageOrOptions?: string | { message?: string, timeout?: number, intervals?: number[] }) => BaseMatchers<Promise<void>, T> & {
|
||||
/**
|
||||
* If you know how to test something, `.not` lets you test its opposite.
|
||||
*/
|
||||
not: BaseMatchers<Promise<void>, T>;
|
||||
};
|
||||
poll: <T = unknown>(actual: () => T | Promise<T>, messageOrOptions?: string | { message?: string, timeout?: number, intervals?: number[] }) => PollMatchers<Promise<void>, T, ExtendedMatchers>;
|
||||
extend<MoreMatchers extends Record<string, (this: ExpectMatcherState, receiver: any, ...args: any[]) => MatcherReturnType | Promise<MatcherReturnType>>>(matchers: MoreMatchers): Expect<ExtendedMatchers & MoreMatchers>;
|
||||
configure: (configuration: {
|
||||
message?: string,
|
||||
|
|
|
|||
Loading…
Reference in a new issue