Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/playwright-core/src/DEPS.list
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@
**

[inprocess.ts]
common/
utils/

[outofprocess.ts]
client/
Expand Down
4 changes: 2 additions & 2 deletions packages/playwright-core/src/client/android.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,7 +31,7 @@ import type { Page } from './page';
import type * as types from './types';
import type * as api from '../../types/types';
import type { AndroidServerLauncherImpl } from '../androidServerImpl';
import type { Platform } from '../common/platform';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

type Direction = 'down' | 'up' | 'left' | 'right';
Expand DownExpand Up@@ -72,7 +72,7 @@ export class Android extends ChannelOwner<channels.AndroidChannel> implements ap
const headers = { 'x-playwright-browser': 'android', ...options.headers };
const localUtils = this._connection.localUtils();
const connectParams: channels.LocalUtilsConnectParams = { wsEndpoint, headers, slowMo: options.slowMo, timeout: options.timeout };
const { pipe } = await localUtils._channel.connect(connectParams);
const { pipe } = await localUtils.connect(connectParams);
const closePipe = () => pipe.close().catch(() => {});
const connection = new Connection(localUtils, this._platform, this._instrumentation);
connection.markAsRemote();
Expand Down
4 changes: 2 additions & 2 deletions packages/playwright-core/src/client/browserContext.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,8 +45,8 @@ import type { BrowserType } from './browserType';
import type { BrowserContextOptions, Headers, LaunchOptions, StorageState, WaitForEventOptions } from './types';
import type * as structs from '../../types/structs';
import type * as api from '../../types/types';
import type { Platform } from '../common/platform';
import type { URLMatch } from '../utils/isomorphic/urlMatch';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel> implements api.BrowserContext {
Expand DownExpand Up@@ -485,7 +485,7 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel>
const needCompressed = harParams.path.endsWith('.zip');
if (isCompressed && !needCompressed) {
await artifact.saveAs(harParams.path + '.tmp');
await this._connection.localUtils()._channel.harUnzip({ zipFile: harParams.path + '.tmp', harFile: harParams.path });
await this._connection.localUtils().harUnzip({ zipFile: harParams.path + '.tmp', harFile: harParams.path });
} else {
await artifact.saveAs(harParams.path);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/browserType.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -133,7 +133,7 @@ export class BrowserType extends ChannelOwner<channels.BrowserTypeChannel> imple
};
if ((params as any).__testHookRedirectPortForwarding)
connectParams.socksProxyRedirectPortForTest = (params as any).__testHookRedirectPortForwarding;
const { pipe, headers: connectHeaders } = await localUtils._channel.connect(connectParams);
const { pipe, headers: connectHeaders } = await localUtils.connect(connectParams);
const closePipe = () => pipe.close().catch(() => {});
const connection = new Connection(localUtils, this._platform, this._instrumentation);
connection.markAsRemote();
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/channelOwner.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,8 +24,8 @@ import { zones } from '../utils/zones';
import type { ClientInstrumentation } from './clientInstrumentation';
import type { Connection } from './connection';
import type { Logger } from './types';
import type { Platform } from '../common/platform';
import type { ValidatorContext } from '../protocol/validator';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

type Listener = (...args: any[]) => void;
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/clientHelper.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,7 +18,7 @@
import { isString } from '../utils/rtti';

import type * as types from './types';
import type { Platform } from '../common/platform';
import type { Platform } from '../utils/platform';

export function envObjectToArray(env: types.Env): { name: string, value: string }[] {
const result: { name: string, value: string }[] = [];
Expand Down
4 changes: 2 additions & 2 deletions packages/playwright-core/src/client/connection.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -47,8 +47,8 @@ import { formatCallLog, rewriteErrorMessage } from '../utils/stackTrace';
import { zones } from '../utils/zones';

import type { ClientInstrumentation } from './clientInstrumentation';
import type { Platform } from '../common/platform';
import type { ValidatorContext } from '../protocol/validator';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

class Root extends ChannelOwner<channels.RootChannel> {
Expand DownExpand Up@@ -142,7 +142,7 @@ export class Connection extends EventEmitter {
const location = frames[0] ? { file: frames[0].file, line: frames[0].line, column: frames[0].column } : undefined;
const metadata: channels.Metadata = { apiName, location, internal: !apiName, stepId };
if (this._tracingCount && frames && type !== 'LocalUtils')
this._localUtils?._channel.addStackToTracingNoReply({ callData: { stack: frames, id } }).catch(() => {});
this._localUtils?.addStackToTracingNoReply({ callData: { stack: frames, id } }).catch(() => {});
// We need to exit zones before calling into the server, otherwise
// when we receive events from the server, we would be in an API zone.
zones.empty().run(() => this.onmessage({ ...message, metadata }));
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/consoleMessage.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,7 +18,7 @@ import { JSHandle } from './jsHandle';
import { Page } from './page';

import type * as api from '../../types/types';
import type { Platform } from '../common/platform';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

type ConsoleMessageLocation = channels.BrowserContextConsoleEvent['location'];
Expand Down
9 changes: 5 additions & 4 deletions packages/playwright-core/src/client/elementHandle.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,7 +31,7 @@ import type { Locator } from './locator';
import type { FilePayload, Rect, SelectOption, SelectOptionOptions } from './types';
import type * as structs from '../../types/structs';
import type * as api from '../../types/types';
import type { Platform } from '../common/platform';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

const pipelineAsync = promisify(pipeline);
Expand DownExpand Up@@ -192,12 +192,13 @@ export class ElementHandle<T extends Node = Node> extends JSHandle<T> implements
return value === undefined ? null : value;
}

async screenshot(options: Omit<channels.ElementHandleScreenshotOptions, 'mask'> & { path?: string, mask?: Locator[] } = {}): Promise<Buffer> {
async screenshot(options: Omit<channels.ElementHandleScreenshotOptions, 'mask'> & { path?: string, mask?: api.Locator[] } = {}): Promise<Buffer> {
const mask = options.mask as Locator[] | undefined;
const copy: channels.ElementHandleScreenshotOptions = { ...options, mask: undefined };
if (!copy.type)
copy.type = determineScreenshotType(options);
if (options.mask) {
copy.mask = options.mask.map(locator => ({
if (mask) {
copy.mask = mask.map(locator => ({
frame: locator._frame._channel,
selector: locator._selector,
}));
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/fetch.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -28,8 +28,8 @@ import type { Playwright } from './playwright';
import type { ClientCertificate, FilePayload, Headers, SetStorageState, StorageState } from './types';
import type { Serializable } from '../../types/structs';
import type * as api from '../../types/types';
import type { Platform } from '../common/platform';
import type { HeadersArray, NameValue } from '../common/types';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';
import type * as fs from 'fs';

Expand Down
6 changes: 3 additions & 3 deletions packages/playwright-core/src/client/harRouter.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,7 +31,7 @@ export class HarRouter {
private _options: { urlMatch?: URLMatch; baseURL?: string; };

static async create(localUtils: LocalUtils, file: string, notFoundAction: HarNotFoundAction, options: { urlMatch?: URLMatch }): Promise<HarRouter> {
const { harId, error } = await localUtils._channel.harOpen({ file });
const { harId, error } = await localUtils.harOpen({ file });
if (error)
throw new Error(error);
return new HarRouter(localUtils, harId!, notFoundAction, options);
Expand All@@ -47,7 +47,7 @@ export class HarRouter {
private async _handle(route: Route) {
const request = route.request();

const response = await this._localUtils._channel.harLookup({
const response = await this._localUtils.harLookup({
harId: this._harId,
url: request.url(),
method: request.method(),
Expand DownExpand Up@@ -103,6 +103,6 @@ export class HarRouter {
}

dispose() {
this._localUtils._channel.harClose({ harId: this._harId }).catch(() => {});
this._localUtils.harClose({ harId: this._harId }).catch(() => {});
}
}
40 changes: 40 additions & 0 deletions packages/playwright-core/src/client/localUtils.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,8 +15,10 @@
*/

import { ChannelOwner } from './channelOwner';
import * as localUtils from '../utils/localUtils';

import type { Size } from './types';
import type { HarBackend } from '../utils/harBackend';
import type * as channels from '@protocol/channels';

type DeviceDescriptor = {
Expand All@@ -31,6 +33,8 @@ type Devices = { [name: string]: DeviceDescriptor };

export class LocalUtils extends ChannelOwner<channels.LocalUtilsChannel> {
readonly devices: Devices;
private _harBackends = new Map<string, HarBackend>();
private _stackSessions = new Map<string, localUtils.StackSession>();

constructor(parent: ChannelOwner, type: string, guid: string, initializer: channels.LocalUtilsInitializer) {
super(parent, type, guid, initializer);
Expand All@@ -39,4 +43,40 @@ export class LocalUtils extends ChannelOwner<channels.LocalUtilsChannel> {
for (const { name, descriptor } of initializer.deviceDescriptors)
this.devices[name] = descriptor;
}

async zip(params: channels.LocalUtilsZipParams): Promise<void> {
return await localUtils.zip(this._platform, this._stackSessions, params);
}

async harOpen(params: channels.LocalUtilsHarOpenParams): Promise<channels.LocalUtilsHarOpenResult> {
return await localUtils.harOpen(this._harBackends, params);
}

async harLookup(params: channels.LocalUtilsHarLookupParams): Promise<channels.LocalUtilsHarLookupResult> {
return await localUtils.harLookup(this._harBackends, params);
}

async harClose(params: channels.LocalUtilsHarCloseParams): Promise<void> {
return await localUtils.harClose(this._harBackends, params);
}

async harUnzip(params: channels.LocalUtilsHarUnzipParams): Promise<void> {
return await localUtils.harUnzip(params);
}

async tracingStarted(params: channels.LocalUtilsTracingStartedParams): Promise<channels.LocalUtilsTracingStartedResult> {
return await localUtils.tracingStarted(this._stackSessions, params);
}

async traceDiscarded(params: channels.LocalUtilsTraceDiscardedParams): Promise<void> {
return await localUtils.traceDiscarded(this._platform, this._stackSessions, params);
}

async addStackToTracingNoReply(params: channels.LocalUtilsAddStackToTracingNoReplyParams): Promise<void> {
return await localUtils.addStackToTracingNoReply(this._stackSessions, params);
}

async connect(params: channels.LocalUtilsConnectParams): Promise<channels.LocalUtilsConnectResult> {
return await this._channel.connect(params);
}
}
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/selectors.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@
import { ChannelOwner } from './channelOwner';
import { evaluationScript } from './clientHelper';
import { setTestIdAttribute, testIdAttributeName } from './locator';
import { nodePlatform } from '../common/platform';
import { nodePlatform } from '../utils/platform';

import type { SelectorEngine } from './types';
import type * as api from '../../types/types';
Expand Down
10 changes: 5 additions & 5 deletions packages/playwright-core/src/client/tracing.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -69,7 +69,7 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
this._isTracing = true;
this._connection.setIsTracing(true);
}
const result = await this._connection.localUtils()._channel.tracingStarted({ tracesDir: this._tracesDir, traceName });
const result = await this._connection.localUtils().tracingStarted({ tracesDir: this._tracesDir, traceName });
this._stacksId = result.stacksId;
}

Expand All@@ -89,15 +89,15 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
// Not interested in artifacts.
await this._channel.tracingStopChunk({ mode: 'discard' });
if (this._stacksId)
await this._connection.localUtils()._channel.traceDiscarded({ stacksId: this._stacksId });
await this._connection.localUtils().traceDiscarded({ stacksId: this._stacksId });
return;
}

const isLocal = !this._connection.isRemote();

if (isLocal) {
const result = await this._channel.tracingStopChunk({ mode: 'entries' });
await this._connection.localUtils()._channel.zip({ zipFile: filePath, entries: result.entries!, mode: 'write', stacksId: this._stacksId, includeSources: this._includeSources });
await this._connection.localUtils().zip({ zipFile: filePath, entries: result.entries!, mode: 'write', stacksId: this._stacksId, includeSources: this._includeSources });
return;
}

Expand All@@ -106,7 +106,7 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
// The artifact may be missing if the browser closed while stopping tracing.
if (!result.artifact) {
if (this._stacksId)
await this._connection.localUtils()._channel.traceDiscarded({ stacksId: this._stacksId });
await this._connection.localUtils().traceDiscarded({ stacksId: this._stacksId });
return;
}

Expand All@@ -115,7 +115,7 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
await artifact.saveAs(filePath);
await artifact.delete();

await this._connection.localUtils()._channel.zip({ zipFile: filePath, entries: [], mode: 'append', stacksId: this._stacksId, includeSources: this._includeSources });
await this._connection.localUtils().zip({ zipFile: filePath, entries: [], mode: 'append', stacksId: this._stacksId, includeSources: this._includeSources });
}

_resetStackCounter() {
Expand Down
3 changes: 2 additions & 1 deletion packages/playwright-core/src/common/DEPS.list
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
[*]
../utils/
../utilsBundle.ts
../utilsBundle.ts
../zipBundle.ts
23 changes: 23 additions & 0 deletions packages/playwright-core/src/common/progress.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
/**
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

export interface Progress {
log(message: string): void;
timeUntilDeadline(): number;
isRunning(): boolean;
cleanupWhenAborted(cleanup: () => any): void;
throwIfAborted(): void;
}
2 changes: 1 addition & 1 deletion packages/playwright-core/src/inProcessFactory.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -20,8 +20,8 @@ import { Connection } from './client/connection';
import { DispatcherConnection, PlaywrightDispatcher, RootDispatcher, createPlaywright } from './server';

import type { Playwright as PlaywrightAPI } from './client/playwright';
import type { Platform } from './common/platform';
import type { Language } from './utils';
import type { Platform } from './utils/platform';

export function createInProcessPlaywright(platform: Platform): PlaywrightAPI {
const playwright = createPlaywright({ sdkLanguage: (process.env.PW_LANG_NAME as Language | undefined) || 'javascript' });
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/inprocess.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@
* limitations under the License.
*/

import { nodePlatform } from './common/platform';
import { createInProcessPlaywright } from './inProcessFactory';
import { nodePlatform } from './utils/platform';

module.exports = createInProcessPlaywright(nodePlatform);
2 changes: 1 addition & 1 deletion packages/playwright-core/src/outofprocess.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,9 +18,9 @@ import * as childProcess from 'child_process';
import * as path from 'path';

import { Connection } from './client/connection';
import { nodePlatform } from './common/platform';
import { PipeTransport } from './protocol/transport';
import { ManualPromise } from './utils/manualPromise';
import { nodePlatform } from './utils/platform';

import type { Playwright } from './client/playwright';

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
chore: short-cut localUtils usage in JS client by pavelfeldman · Pull Request #34690 · microsoft/playwright · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/playwright-core/src/DEPS.list
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@
**

[inprocess.ts]
common/
utils/

[outofprocess.ts]
client/
Expand Down
4 changes: 2 additions & 2 deletions packages/playwright-core/src/client/android.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,7 +31,7 @@ import type { Page } from './page';
import type * as types from './types';
import type * as api from '../../types/types';
import type { AndroidServerLauncherImpl } from '../androidServerImpl';
import type { Platform } from '../common/platform';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

type Direction = 'down' | 'up' | 'left' | 'right';
Expand DownExpand Up@@ -72,7 +72,7 @@ export class Android extends ChannelOwner<channels.AndroidChannel> implements ap
const headers = { 'x-playwright-browser': 'android', ...options.headers };
const localUtils = this._connection.localUtils();
const connectParams: channels.LocalUtilsConnectParams = { wsEndpoint, headers, slowMo: options.slowMo, timeout: options.timeout };
const { pipe } = await localUtils._channel.connect(connectParams);
const { pipe } = await localUtils.connect(connectParams);
const closePipe = () => pipe.close().catch(() => {});
const connection = new Connection(localUtils, this._platform, this._instrumentation);
connection.markAsRemote();
Expand Down
4 changes: 2 additions & 2 deletions packages/playwright-core/src/client/browserContext.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,8 +45,8 @@ import type { BrowserType } from './browserType';
import type { BrowserContextOptions, Headers, LaunchOptions, StorageState, WaitForEventOptions } from './types';
import type * as structs from '../../types/structs';
import type * as api from '../../types/types';
import type { Platform } from '../common/platform';
import type { URLMatch } from '../utils/isomorphic/urlMatch';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel> implements api.BrowserContext {
Expand DownExpand Up@@ -485,7 +485,7 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel>
const needCompressed = harParams.path.endsWith('.zip');
if (isCompressed && !needCompressed) {
await artifact.saveAs(harParams.path + '.tmp');
await this._connection.localUtils()._channel.harUnzip({ zipFile: harParams.path + '.tmp', harFile: harParams.path });
await this._connection.localUtils().harUnzip({ zipFile: harParams.path + '.tmp', harFile: harParams.path });
} else {
await artifact.saveAs(harParams.path);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/browserType.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -133,7 +133,7 @@ export class BrowserType extends ChannelOwner<channels.BrowserTypeChannel> imple
};
if ((params as any).__testHookRedirectPortForwarding)
connectParams.socksProxyRedirectPortForTest = (params as any).__testHookRedirectPortForwarding;
const { pipe, headers: connectHeaders } = await localUtils._channel.connect(connectParams);
const { pipe, headers: connectHeaders } = await localUtils.connect(connectParams);
const closePipe = () => pipe.close().catch(() => {});
const connection = new Connection(localUtils, this._platform, this._instrumentation);
connection.markAsRemote();
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/channelOwner.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,8 +24,8 @@ import { zones } from '../utils/zones';
import type { ClientInstrumentation } from './clientInstrumentation';
import type { Connection } from './connection';
import type { Logger } from './types';
import type { Platform } from '../common/platform';
import type { ValidatorContext } from '../protocol/validator';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

type Listener = (...args: any[]) => void;
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/clientHelper.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,7 +18,7 @@
import { isString } from '../utils/rtti';

import type * as types from './types';
import type { Platform } from '../common/platform';
import type { Platform } from '../utils/platform';

export function envObjectToArray(env: types.Env): { name: string, value: string }[] {
const result: { name: string, value: string }[] = [];
Expand Down
4 changes: 2 additions & 2 deletions packages/playwright-core/src/client/connection.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -47,8 +47,8 @@ import { formatCallLog, rewriteErrorMessage } from '../utils/stackTrace';
import { zones } from '../utils/zones';

import type { ClientInstrumentation } from './clientInstrumentation';
import type { Platform } from '../common/platform';
import type { ValidatorContext } from '../protocol/validator';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

class Root extends ChannelOwner<channels.RootChannel> {
Expand DownExpand Up@@ -142,7 +142,7 @@ export class Connection extends EventEmitter {
const location = frames[0] ? { file: frames[0].file, line: frames[0].line, column: frames[0].column } : undefined;
const metadata: channels.Metadata = { apiName, location, internal: !apiName, stepId };
if (this._tracingCount && frames && type !== 'LocalUtils')
this._localUtils?._channel.addStackToTracingNoReply({ callData: { stack: frames, id } }).catch(() => {});
this._localUtils?.addStackToTracingNoReply({ callData: { stack: frames, id } }).catch(() => {});
// We need to exit zones before calling into the server, otherwise
// when we receive events from the server, we would be in an API zone.
zones.empty().run(() => this.onmessage({ ...message, metadata }));
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/consoleMessage.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,7 +18,7 @@ import { JSHandle } from './jsHandle';
import { Page } from './page';

import type * as api from '../../types/types';
import type { Platform } from '../common/platform';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

type ConsoleMessageLocation = channels.BrowserContextConsoleEvent['location'];
Expand Down
9 changes: 5 additions & 4 deletions packages/playwright-core/src/client/elementHandle.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,7 +31,7 @@ import type { Locator } from './locator';
import type { FilePayload, Rect, SelectOption, SelectOptionOptions } from './types';
import type * as structs from '../../types/structs';
import type * as api from '../../types/types';
import type { Platform } from '../common/platform';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

const pipelineAsync = promisify(pipeline);
Expand DownExpand Up@@ -192,12 +192,13 @@ export class ElementHandle<T extends Node = Node> extends JSHandle<T> implements
return value === undefined ? null : value;
}

async screenshot(options: Omit<channels.ElementHandleScreenshotOptions, 'mask'> & { path?: string, mask?: Locator[] } = {}): Promise<Buffer> {
async screenshot(options: Omit<channels.ElementHandleScreenshotOptions, 'mask'> & { path?: string, mask?: api.Locator[] } = {}): Promise<Buffer> {
const mask = options.mask as Locator[] | undefined;
const copy: channels.ElementHandleScreenshotOptions = { ...options, mask: undefined };
if (!copy.type)
copy.type = determineScreenshotType(options);
if (options.mask) {
copy.mask = options.mask.map(locator => ({
if (mask) {
copy.mask = mask.map(locator => ({
frame: locator._frame._channel,
selector: locator._selector,
}));
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/fetch.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -28,8 +28,8 @@ import type { Playwright } from './playwright';
import type { ClientCertificate, FilePayload, Headers, SetStorageState, StorageState } from './types';
import type { Serializable } from '../../types/structs';
import type * as api from '../../types/types';
import type { Platform } from '../common/platform';
import type { HeadersArray, NameValue } from '../common/types';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';
import type * as fs from 'fs';

Expand Down
6 changes: 3 additions & 3 deletions packages/playwright-core/src/client/harRouter.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,7 +31,7 @@ export class HarRouter {
private _options: { urlMatch?: URLMatch; baseURL?: string; };

static async create(localUtils: LocalUtils, file: string, notFoundAction: HarNotFoundAction, options: { urlMatch?: URLMatch }): Promise<HarRouter> {
const { harId, error } = await localUtils._channel.harOpen({ file });
const { harId, error } = await localUtils.harOpen({ file });
if (error)
throw new Error(error);
return new HarRouter(localUtils, harId!, notFoundAction, options);
Expand All@@ -47,7 +47,7 @@ export class HarRouter {
private async _handle(route: Route) {
const request = route.request();

const response = await this._localUtils._channel.harLookup({
const response = await this._localUtils.harLookup({
harId: this._harId,
url: request.url(),
method: request.method(),
Expand DownExpand Up@@ -103,6 +103,6 @@ export class HarRouter {
}

dispose() {
this._localUtils._channel.harClose({ harId: this._harId }).catch(() => {});
this._localUtils.harClose({ harId: this._harId }).catch(() => {});
}
}
40 changes: 40 additions & 0 deletions packages/playwright-core/src/client/localUtils.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,8 +15,10 @@
*/

import { ChannelOwner } from './channelOwner';
import * as localUtils from '../utils/localUtils';

import type { Size } from './types';
import type { HarBackend } from '../utils/harBackend';
import type * as channels from '@protocol/channels';

type DeviceDescriptor = {
Expand All@@ -31,6 +33,8 @@ type Devices = { [name: string]: DeviceDescriptor };

export class LocalUtils extends ChannelOwner<channels.LocalUtilsChannel> {
readonly devices: Devices;
private _harBackends = new Map<string, HarBackend>();
private _stackSessions = new Map<string, localUtils.StackSession>();

constructor(parent: ChannelOwner, type: string, guid: string, initializer: channels.LocalUtilsInitializer) {
super(parent, type, guid, initializer);
Expand All@@ -39,4 +43,40 @@ export class LocalUtils extends ChannelOwner<channels.LocalUtilsChannel> {
for (const { name, descriptor } of initializer.deviceDescriptors)
this.devices[name] = descriptor;
}

async zip(params: channels.LocalUtilsZipParams): Promise<void> {
return await localUtils.zip(this._platform, this._stackSessions, params);
}

async harOpen(params: channels.LocalUtilsHarOpenParams): Promise<channels.LocalUtilsHarOpenResult> {
return await localUtils.harOpen(this._harBackends, params);
}

async harLookup(params: channels.LocalUtilsHarLookupParams): Promise<channels.LocalUtilsHarLookupResult> {
return await localUtils.harLookup(this._harBackends, params);
}

async harClose(params: channels.LocalUtilsHarCloseParams): Promise<void> {
return await localUtils.harClose(this._harBackends, params);
}

async harUnzip(params: channels.LocalUtilsHarUnzipParams): Promise<void> {
return await localUtils.harUnzip(params);
}

async tracingStarted(params: channels.LocalUtilsTracingStartedParams): Promise<channels.LocalUtilsTracingStartedResult> {
return await localUtils.tracingStarted(this._stackSessions, params);
}

async traceDiscarded(params: channels.LocalUtilsTraceDiscardedParams): Promise<void> {
return await localUtils.traceDiscarded(this._platform, this._stackSessions, params);
}

async addStackToTracingNoReply(params: channels.LocalUtilsAddStackToTracingNoReplyParams): Promise<void> {
return await localUtils.addStackToTracingNoReply(this._stackSessions, params);
}

async connect(params: channels.LocalUtilsConnectParams): Promise<channels.LocalUtilsConnectResult> {
return await this._channel.connect(params);
}
}
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/selectors.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@
import { ChannelOwner } from './channelOwner';
import { evaluationScript } from './clientHelper';
import { setTestIdAttribute, testIdAttributeName } from './locator';
import { nodePlatform } from '../common/platform';
import { nodePlatform } from '../utils/platform';

import type { SelectorEngine } from './types';
import type * as api from '../../types/types';
Expand Down
10 changes: 5 additions & 5 deletions packages/playwright-core/src/client/tracing.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -69,7 +69,7 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
this._isTracing = true;
this._connection.setIsTracing(true);
}
const result = await this._connection.localUtils()._channel.tracingStarted({ tracesDir: this._tracesDir, traceName });
const result = await this._connection.localUtils().tracingStarted({ tracesDir: this._tracesDir, traceName });
this._stacksId = result.stacksId;
}

Expand All@@ -89,15 +89,15 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
// Not interested in artifacts.
await this._channel.tracingStopChunk({ mode: 'discard' });
if (this._stacksId)
await this._connection.localUtils()._channel.traceDiscarded({ stacksId: this._stacksId });
await this._connection.localUtils().traceDiscarded({ stacksId: this._stacksId });
return;
}

const isLocal = !this._connection.isRemote();

if (isLocal) {
const result = await this._channel.tracingStopChunk({ mode: 'entries' });
await this._connection.localUtils()._channel.zip({ zipFile: filePath, entries: result.entries!, mode: 'write', stacksId: this._stacksId, includeSources: this._includeSources });
await this._connection.localUtils().zip({ zipFile: filePath, entries: result.entries!, mode: 'write', stacksId: this._stacksId, includeSources: this._includeSources });
return;
}

Expand All@@ -106,7 +106,7 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
// The artifact may be missing if the browser closed while stopping tracing.
if (!result.artifact) {
if (this._stacksId)
await this._connection.localUtils()._channel.traceDiscarded({ stacksId: this._stacksId });
await this._connection.localUtils().traceDiscarded({ stacksId: this._stacksId });
return;
}

Expand All@@ -115,7 +115,7 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
await artifact.saveAs(filePath);
await artifact.delete();

await this._connection.localUtils()._channel.zip({ zipFile: filePath, entries: [], mode: 'append', stacksId: this._stacksId, includeSources: this._includeSources });
await this._connection.localUtils().zip({ zipFile: filePath, entries: [], mode: 'append', stacksId: this._stacksId, includeSources: this._includeSources });
}

_resetStackCounter() {
Expand Down
3 changes: 2 additions & 1 deletion packages/playwright-core/src/common/DEPS.list
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
[*]
../utils/
../utilsBundle.ts
../utilsBundle.ts
../zipBundle.ts
23 changes: 23 additions & 0 deletions packages/playwright-core/src/common/progress.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
/**
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

export interface Progress {
log(message: string): void;
timeUntilDeadline(): number;
isRunning(): boolean;
cleanupWhenAborted(cleanup: () => any): void;
throwIfAborted(): void;
}
2 changes: 1 addition & 1 deletion packages/playwright-core/src/inProcessFactory.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -20,8 +20,8 @@ import { Connection } from './client/connection';
import { DispatcherConnection, PlaywrightDispatcher, RootDispatcher, createPlaywright } from './server';

import type { Playwright as PlaywrightAPI } from './client/playwright';
import type { Platform } from './common/platform';
import type { Language } from './utils';
import type { Platform } from './utils/platform';

export function createInProcessPlaywright(platform: Platform): PlaywrightAPI {
const playwright = createPlaywright({ sdkLanguage: (process.env.PW_LANG_NAME as Language | undefined) || 'javascript' });
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/inprocess.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@
* limitations under the License.
*/

import { nodePlatform } from './common/platform';
import { createInProcessPlaywright } from './inProcessFactory';
import { nodePlatform } from './utils/platform';

module.exports = createInProcessPlaywright(nodePlatform);
2 changes: 1 addition & 1 deletion packages/playwright-core/src/outofprocess.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,9 +18,9 @@ import * as childProcess from 'child_process';
import * as path from 'path';

import { Connection } from './client/connection';
import { nodePlatform } from './common/platform';
import { PipeTransport } from './protocol/transport';
import { ManualPromise } from './utils/manualPromise';
import { nodePlatform } from './utils/platform';

import type { Playwright } from './client/playwright';

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' chore: short-cut localUtils usage in JS client by pavelfeldman · Pull Request #34690 · microsoft/playwright · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/playwright-core/src/DEPS.list
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@
**

[inprocess.ts]
common/
utils/

[outofprocess.ts]
client/
Expand Down
4 changes: 2 additions & 2 deletions packages/playwright-core/src/client/android.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,7 +31,7 @@ import type { Page } from './page';
import type * as types from './types';
import type * as api from '../../types/types';
import type { AndroidServerLauncherImpl } from '../androidServerImpl';
import type { Platform } from '../common/platform';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

type Direction = 'down' | 'up' | 'left' | 'right';
Expand DownExpand Up@@ -72,7 +72,7 @@ export class Android extends ChannelOwner<channels.AndroidChannel> implements ap
const headers = { 'x-playwright-browser': 'android', ...options.headers };
const localUtils = this._connection.localUtils();
const connectParams: channels.LocalUtilsConnectParams = { wsEndpoint, headers, slowMo: options.slowMo, timeout: options.timeout };
const { pipe } = await localUtils._channel.connect(connectParams);
const { pipe } = await localUtils.connect(connectParams);
const closePipe = () => pipe.close().catch(() => {});
const connection = new Connection(localUtils, this._platform, this._instrumentation);
connection.markAsRemote();
Expand Down
4 changes: 2 additions & 2 deletions packages/playwright-core/src/client/browserContext.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,8 +45,8 @@ import type { BrowserType } from './browserType';
import type { BrowserContextOptions, Headers, LaunchOptions, StorageState, WaitForEventOptions } from './types';
import type * as structs from '../../types/structs';
import type * as api from '../../types/types';
import type { Platform } from '../common/platform';
import type { URLMatch } from '../utils/isomorphic/urlMatch';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel> implements api.BrowserContext {
Expand DownExpand Up@@ -485,7 +485,7 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel>
const needCompressed = harParams.path.endsWith('.zip');
if (isCompressed && !needCompressed) {
await artifact.saveAs(harParams.path + '.tmp');
await this._connection.localUtils()._channel.harUnzip({ zipFile: harParams.path + '.tmp', harFile: harParams.path });
await this._connection.localUtils().harUnzip({ zipFile: harParams.path + '.tmp', harFile: harParams.path });
} else {
await artifact.saveAs(harParams.path);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/browserType.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -133,7 +133,7 @@ export class BrowserType extends ChannelOwner<channels.BrowserTypeChannel> imple
};
if ((params as any).__testHookRedirectPortForwarding)
connectParams.socksProxyRedirectPortForTest = (params as any).__testHookRedirectPortForwarding;
const { pipe, headers: connectHeaders } = await localUtils._channel.connect(connectParams);
const { pipe, headers: connectHeaders } = await localUtils.connect(connectParams);
const closePipe = () => pipe.close().catch(() => {});
const connection = new Connection(localUtils, this._platform, this._instrumentation);
connection.markAsRemote();
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/channelOwner.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,8 +24,8 @@ import { zones } from '../utils/zones';
import type { ClientInstrumentation } from './clientInstrumentation';
import type { Connection } from './connection';
import type { Logger } from './types';
import type { Platform } from '../common/platform';
import type { ValidatorContext } from '../protocol/validator';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

type Listener = (...args: any[]) => void;
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/clientHelper.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,7 +18,7 @@
import { isString } from '../utils/rtti';

import type * as types from './types';
import type { Platform } from '../common/platform';
import type { Platform } from '../utils/platform';

export function envObjectToArray(env: types.Env): { name: string, value: string }[] {
const result: { name: string, value: string }[] = [];
Expand Down
4 changes: 2 additions & 2 deletions packages/playwright-core/src/client/connection.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -47,8 +47,8 @@ import { formatCallLog, rewriteErrorMessage } from '../utils/stackTrace';
import { zones } from '../utils/zones';

import type { ClientInstrumentation } from './clientInstrumentation';
import type { Platform } from '../common/platform';
import type { ValidatorContext } from '../protocol/validator';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

class Root extends ChannelOwner<channels.RootChannel> {
Expand DownExpand Up@@ -142,7 +142,7 @@ export class Connection extends EventEmitter {
const location = frames[0] ? { file: frames[0].file, line: frames[0].line, column: frames[0].column } : undefined;
const metadata: channels.Metadata = { apiName, location, internal: !apiName, stepId };
if (this._tracingCount && frames && type !== 'LocalUtils')
this._localUtils?._channel.addStackToTracingNoReply({ callData: { stack: frames, id } }).catch(() => {});
this._localUtils?.addStackToTracingNoReply({ callData: { stack: frames, id } }).catch(() => {});
// We need to exit zones before calling into the server, otherwise
// when we receive events from the server, we would be in an API zone.
zones.empty().run(() => this.onmessage({ ...message, metadata }));
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/consoleMessage.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,7 +18,7 @@ import { JSHandle } from './jsHandle';
import { Page } from './page';

import type * as api from '../../types/types';
import type { Platform } from '../common/platform';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

type ConsoleMessageLocation = channels.BrowserContextConsoleEvent['location'];
Expand Down
9 changes: 5 additions & 4 deletions packages/playwright-core/src/client/elementHandle.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,7 +31,7 @@ import type { Locator } from './locator';
import type { FilePayload, Rect, SelectOption, SelectOptionOptions } from './types';
import type * as structs from '../../types/structs';
import type * as api from '../../types/types';
import type { Platform } from '../common/platform';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

const pipelineAsync = promisify(pipeline);
Expand DownExpand Up@@ -192,12 +192,13 @@ export class ElementHandle<T extends Node = Node> extends JSHandle<T> implements
return value === undefined ? null : value;
}

async screenshot(options: Omit<channels.ElementHandleScreenshotOptions, 'mask'> & { path?: string, mask?: Locator[] } = {}): Promise<Buffer> {
async screenshot(options: Omit<channels.ElementHandleScreenshotOptions, 'mask'> & { path?: string, mask?: api.Locator[] } = {}): Promise<Buffer> {
const mask = options.mask as Locator[] | undefined;
const copy: channels.ElementHandleScreenshotOptions = { ...options, mask: undefined };
if (!copy.type)
copy.type = determineScreenshotType(options);
if (options.mask) {
copy.mask = options.mask.map(locator => ({
if (mask) {
copy.mask = mask.map(locator => ({
frame: locator._frame._channel,
selector: locator._selector,
}));
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/fetch.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -28,8 +28,8 @@ import type { Playwright } from './playwright';
import type { ClientCertificate, FilePayload, Headers, SetStorageState, StorageState } from './types';
import type { Serializable } from '../../types/structs';
import type * as api from '../../types/types';
import type { Platform } from '../common/platform';
import type { HeadersArray, NameValue } from '../common/types';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';
import type * as fs from 'fs';

Expand Down
6 changes: 3 additions & 3 deletions packages/playwright-core/src/client/harRouter.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,7 +31,7 @@ export class HarRouter {
private _options: { urlMatch?: URLMatch; baseURL?: string; };

static async create(localUtils: LocalUtils, file: string, notFoundAction: HarNotFoundAction, options: { urlMatch?: URLMatch }): Promise<HarRouter> {
const { harId, error } = await localUtils._channel.harOpen({ file });
const { harId, error } = await localUtils.harOpen({ file });
if (error)
throw new Error(error);
return new HarRouter(localUtils, harId!, notFoundAction, options);
Expand All@@ -47,7 +47,7 @@ export class HarRouter {
private async _handle(route: Route) {
const request = route.request();

const response = await this._localUtils._channel.harLookup({
const response = await this._localUtils.harLookup({
harId: this._harId,
url: request.url(),
method: request.method(),
Expand DownExpand Up@@ -103,6 +103,6 @@ export class HarRouter {
}

dispose() {
this._localUtils._channel.harClose({ harId: this._harId }).catch(() => {});
this._localUtils.harClose({ harId: this._harId }).catch(() => {});
}
}
40 changes: 40 additions & 0 deletions packages/playwright-core/src/client/localUtils.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,8 +15,10 @@
*/

import { ChannelOwner } from './channelOwner';
import * as localUtils from '../utils/localUtils';

import type { Size } from './types';
import type { HarBackend } from '../utils/harBackend';
import type * as channels from '@protocol/channels';

type DeviceDescriptor = {
Expand All@@ -31,6 +33,8 @@ type Devices = { [name: string]: DeviceDescriptor };

export class LocalUtils extends ChannelOwner<channels.LocalUtilsChannel> {
readonly devices: Devices;
private _harBackends = new Map<string, HarBackend>();
private _stackSessions = new Map<string, localUtils.StackSession>();

constructor(parent: ChannelOwner, type: string, guid: string, initializer: channels.LocalUtilsInitializer) {
super(parent, type, guid, initializer);
Expand All@@ -39,4 +43,40 @@ export class LocalUtils extends ChannelOwner<channels.LocalUtilsChannel> {
for (const { name, descriptor } of initializer.deviceDescriptors)
this.devices[name] = descriptor;
}

async zip(params: channels.LocalUtilsZipParams): Promise<void> {
return await localUtils.zip(this._platform, this._stackSessions, params);
}

async harOpen(params: channels.LocalUtilsHarOpenParams): Promise<channels.LocalUtilsHarOpenResult> {
return await localUtils.harOpen(this._harBackends, params);
}

async harLookup(params: channels.LocalUtilsHarLookupParams): Promise<channels.LocalUtilsHarLookupResult> {
return await localUtils.harLookup(this._harBackends, params);
}

async harClose(params: channels.LocalUtilsHarCloseParams): Promise<void> {
return await localUtils.harClose(this._harBackends, params);
}

async harUnzip(params: channels.LocalUtilsHarUnzipParams): Promise<void> {
return await localUtils.harUnzip(params);
}

async tracingStarted(params: channels.LocalUtilsTracingStartedParams): Promise<channels.LocalUtilsTracingStartedResult> {
return await localUtils.tracingStarted(this._stackSessions, params);
}

async traceDiscarded(params: channels.LocalUtilsTraceDiscardedParams): Promise<void> {
return await localUtils.traceDiscarded(this._platform, this._stackSessions, params);
}

async addStackToTracingNoReply(params: channels.LocalUtilsAddStackToTracingNoReplyParams): Promise<void> {
return await localUtils.addStackToTracingNoReply(this._stackSessions, params);
}

async connect(params: channels.LocalUtilsConnectParams): Promise<channels.LocalUtilsConnectResult> {
return await this._channel.connect(params);
}
}
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/selectors.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@
import { ChannelOwner } from './channelOwner';
import { evaluationScript } from './clientHelper';
import { setTestIdAttribute, testIdAttributeName } from './locator';
import { nodePlatform } from '../common/platform';
import { nodePlatform } from '../utils/platform';

import type { SelectorEngine } from './types';
import type * as api from '../../types/types';
Expand Down
10 changes: 5 additions & 5 deletions packages/playwright-core/src/client/tracing.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -69,7 +69,7 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
this._isTracing = true;
this._connection.setIsTracing(true);
}
const result = await this._connection.localUtils()._channel.tracingStarted({ tracesDir: this._tracesDir, traceName });
const result = await this._connection.localUtils().tracingStarted({ tracesDir: this._tracesDir, traceName });
this._stacksId = result.stacksId;
}

Expand All@@ -89,15 +89,15 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
// Not interested in artifacts.
await this._channel.tracingStopChunk({ mode: 'discard' });
if (this._stacksId)
await this._connection.localUtils()._channel.traceDiscarded({ stacksId: this._stacksId });
await this._connection.localUtils().traceDiscarded({ stacksId: this._stacksId });
return;
}

const isLocal = !this._connection.isRemote();

if (isLocal) {
const result = await this._channel.tracingStopChunk({ mode: 'entries' });
await this._connection.localUtils()._channel.zip({ zipFile: filePath, entries: result.entries!, mode: 'write', stacksId: this._stacksId, includeSources: this._includeSources });
await this._connection.localUtils().zip({ zipFile: filePath, entries: result.entries!, mode: 'write', stacksId: this._stacksId, includeSources: this._includeSources });
return;
}

Expand All@@ -106,7 +106,7 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
// The artifact may be missing if the browser closed while stopping tracing.
if (!result.artifact) {
if (this._stacksId)
await this._connection.localUtils()._channel.traceDiscarded({ stacksId: this._stacksId });
await this._connection.localUtils().traceDiscarded({ stacksId: this._stacksId });
return;
}

Expand All@@ -115,7 +115,7 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
await artifact.saveAs(filePath);
await artifact.delete();

await this._connection.localUtils()._channel.zip({ zipFile: filePath, entries: [], mode: 'append', stacksId: this._stacksId, includeSources: this._includeSources });
await this._connection.localUtils().zip({ zipFile: filePath, entries: [], mode: 'append', stacksId: this._stacksId, includeSources: this._includeSources });
}

_resetStackCounter() {
Expand Down
3 changes: 2 additions & 1 deletion packages/playwright-core/src/common/DEPS.list
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
[*]
../utils/
../utilsBundle.ts
../utilsBundle.ts
../zipBundle.ts
23 changes: 23 additions & 0 deletions packages/playwright-core/src/common/progress.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
/**
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

export interface Progress {
log(message: string): void;
timeUntilDeadline(): number;
isRunning(): boolean;
cleanupWhenAborted(cleanup: () => any): void;
throwIfAborted(): void;
}
2 changes: 1 addition & 1 deletion packages/playwright-core/src/inProcessFactory.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -20,8 +20,8 @@ import { Connection } from './client/connection';
import { DispatcherConnection, PlaywrightDispatcher, RootDispatcher, createPlaywright } from './server';

import type { Playwright as PlaywrightAPI } from './client/playwright';
import type { Platform } from './common/platform';
import type { Language } from './utils';
import type { Platform } from './utils/platform';

export function createInProcessPlaywright(platform: Platform): PlaywrightAPI {
const playwright = createPlaywright({ sdkLanguage: (process.env.PW_LANG_NAME as Language | undefined) || 'javascript' });
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/inprocess.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@
* limitations under the License.
*/

import { nodePlatform } from './common/platform';
import { createInProcessPlaywright } from './inProcessFactory';
import { nodePlatform } from './utils/platform';

module.exports = createInProcessPlaywright(nodePlatform);
2 changes: 1 addition & 1 deletion packages/playwright-core/src/outofprocess.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,9 +18,9 @@ import * as childProcess from 'child_process';
import * as path from 'path';

import { Connection } from './client/connection';
import { nodePlatform } from './common/platform';
import { PipeTransport } from './protocol/transport';
import { ManualPromise } from './utils/manualPromise';
import { nodePlatform } from './utils/platform';

import type { Playwright } from './client/playwright';

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' chore: short-cut localUtils usage in JS client by pavelfeldman · Pull Request #34690 · microsoft/playwright · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/playwright-core/src/DEPS.list
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@
**

[inprocess.ts]
common/
utils/

[outofprocess.ts]
client/
Expand Down
4 changes: 2 additions & 2 deletions packages/playwright-core/src/client/android.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,7 +31,7 @@ import type { Page } from './page';
import type * as types from './types';
import type * as api from '../../types/types';
import type { AndroidServerLauncherImpl } from '../androidServerImpl';
import type { Platform } from '../common/platform';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

type Direction = 'down' | 'up' | 'left' | 'right';
Expand DownExpand Up@@ -72,7 +72,7 @@ export class Android extends ChannelOwner<channels.AndroidChannel> implements ap
const headers = { 'x-playwright-browser': 'android', ...options.headers };
const localUtils = this._connection.localUtils();
const connectParams: channels.LocalUtilsConnectParams = { wsEndpoint, headers, slowMo: options.slowMo, timeout: options.timeout };
const { pipe } = await localUtils._channel.connect(connectParams);
const { pipe } = await localUtils.connect(connectParams);
const closePipe = () => pipe.close().catch(() => {});
const connection = new Connection(localUtils, this._platform, this._instrumentation);
connection.markAsRemote();
Expand Down
4 changes: 2 additions & 2 deletions packages/playwright-core/src/client/browserContext.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,8 +45,8 @@ import type { BrowserType } from './browserType';
import type { BrowserContextOptions, Headers, LaunchOptions, StorageState, WaitForEventOptions } from './types';
import type * as structs from '../../types/structs';
import type * as api from '../../types/types';
import type { Platform } from '../common/platform';
import type { URLMatch } from '../utils/isomorphic/urlMatch';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel> implements api.BrowserContext {
Expand DownExpand Up@@ -485,7 +485,7 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel>
const needCompressed = harParams.path.endsWith('.zip');
if (isCompressed && !needCompressed) {
await artifact.saveAs(harParams.path + '.tmp');
await this._connection.localUtils()._channel.harUnzip({ zipFile: harParams.path + '.tmp', harFile: harParams.path });
await this._connection.localUtils().harUnzip({ zipFile: harParams.path + '.tmp', harFile: harParams.path });
} else {
await artifact.saveAs(harParams.path);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/browserType.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -133,7 +133,7 @@ export class BrowserType extends ChannelOwner<channels.BrowserTypeChannel> imple
};
if ((params as any).__testHookRedirectPortForwarding)
connectParams.socksProxyRedirectPortForTest = (params as any).__testHookRedirectPortForwarding;
const { pipe, headers: connectHeaders } = await localUtils._channel.connect(connectParams);
const { pipe, headers: connectHeaders } = await localUtils.connect(connectParams);
const closePipe = () => pipe.close().catch(() => {});
const connection = new Connection(localUtils, this._platform, this._instrumentation);
connection.markAsRemote();
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/channelOwner.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,8 +24,8 @@ import { zones } from '../utils/zones';
import type { ClientInstrumentation } from './clientInstrumentation';
import type { Connection } from './connection';
import type { Logger } from './types';
import type { Platform } from '../common/platform';
import type { ValidatorContext } from '../protocol/validator';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

type Listener = (...args: any[]) => void;
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/clientHelper.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,7 +18,7 @@
import { isString } from '../utils/rtti';

import type * as types from './types';
import type { Platform } from '../common/platform';
import type { Platform } from '../utils/platform';

export function envObjectToArray(env: types.Env): { name: string, value: string }[] {
const result: { name: string, value: string }[] = [];
Expand Down
4 changes: 2 additions & 2 deletions packages/playwright-core/src/client/connection.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -47,8 +47,8 @@ import { formatCallLog, rewriteErrorMessage } from '../utils/stackTrace';
import { zones } from '../utils/zones';

import type { ClientInstrumentation } from './clientInstrumentation';
import type { Platform } from '../common/platform';
import type { ValidatorContext } from '../protocol/validator';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

class Root extends ChannelOwner<channels.RootChannel> {
Expand DownExpand Up@@ -142,7 +142,7 @@ export class Connection extends EventEmitter {
const location = frames[0] ? { file: frames[0].file, line: frames[0].line, column: frames[0].column } : undefined;
const metadata: channels.Metadata = { apiName, location, internal: !apiName, stepId };
if (this._tracingCount && frames && type !== 'LocalUtils')
this._localUtils?._channel.addStackToTracingNoReply({ callData: { stack: frames, id } }).catch(() => {});
this._localUtils?.addStackToTracingNoReply({ callData: { stack: frames, id } }).catch(() => {});
// We need to exit zones before calling into the server, otherwise
// when we receive events from the server, we would be in an API zone.
zones.empty().run(() => this.onmessage({ ...message, metadata }));
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/consoleMessage.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,7 +18,7 @@ import { JSHandle } from './jsHandle';
import { Page } from './page';

import type * as api from '../../types/types';
import type { Platform } from '../common/platform';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

type ConsoleMessageLocation = channels.BrowserContextConsoleEvent['location'];
Expand Down
9 changes: 5 additions & 4 deletions packages/playwright-core/src/client/elementHandle.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,7 +31,7 @@ import type { Locator } from './locator';
import type { FilePayload, Rect, SelectOption, SelectOptionOptions } from './types';
import type * as structs from '../../types/structs';
import type * as api from '../../types/types';
import type { Platform } from '../common/platform';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

const pipelineAsync = promisify(pipeline);
Expand DownExpand Up@@ -192,12 +192,13 @@ export class ElementHandle<T extends Node = Node> extends JSHandle<T> implements
return value === undefined ? null : value;
}

async screenshot(options: Omit<channels.ElementHandleScreenshotOptions, 'mask'> & { path?: string, mask?: Locator[] } = {}): Promise<Buffer> {
async screenshot(options: Omit<channels.ElementHandleScreenshotOptions, 'mask'> & { path?: string, mask?: api.Locator[] } = {}): Promise<Buffer> {
const mask = options.mask as Locator[] | undefined;
const copy: channels.ElementHandleScreenshotOptions = { ...options, mask: undefined };
if (!copy.type)
copy.type = determineScreenshotType(options);
if (options.mask) {
copy.mask = options.mask.map(locator => ({
if (mask) {
copy.mask = mask.map(locator => ({
frame: locator._frame._channel,
selector: locator._selector,
}));
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/fetch.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -28,8 +28,8 @@ import type { Playwright } from './playwright';
import type { ClientCertificate, FilePayload, Headers, SetStorageState, StorageState } from './types';
import type { Serializable } from '../../types/structs';
import type * as api from '../../types/types';
import type { Platform } from '../common/platform';
import type { HeadersArray, NameValue } from '../common/types';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';
import type * as fs from 'fs';

Expand Down
6 changes: 3 additions & 3 deletions packages/playwright-core/src/client/harRouter.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,7 +31,7 @@ export class HarRouter {
private _options: { urlMatch?: URLMatch; baseURL?: string; };

static async create(localUtils: LocalUtils, file: string, notFoundAction: HarNotFoundAction, options: { urlMatch?: URLMatch }): Promise<HarRouter> {
const { harId, error } = await localUtils._channel.harOpen({ file });
const { harId, error } = await localUtils.harOpen({ file });
if (error)
throw new Error(error);
return new HarRouter(localUtils, harId!, notFoundAction, options);
Expand All@@ -47,7 +47,7 @@ export class HarRouter {
private async _handle(route: Route) {
const request = route.request();

const response = await this._localUtils._channel.harLookup({
const response = await this._localUtils.harLookup({
harId: this._harId,
url: request.url(),
method: request.method(),
Expand DownExpand Up@@ -103,6 +103,6 @@ export class HarRouter {
}

dispose() {
this._localUtils._channel.harClose({ harId: this._harId }).catch(() => {});
this._localUtils.harClose({ harId: this._harId }).catch(() => {});
}
}
40 changes: 40 additions & 0 deletions packages/playwright-core/src/client/localUtils.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,8 +15,10 @@
*/

import { ChannelOwner } from './channelOwner';
import * as localUtils from '../utils/localUtils';

import type { Size } from './types';
import type { HarBackend } from '../utils/harBackend';
import type * as channels from '@protocol/channels';

type DeviceDescriptor = {
Expand All@@ -31,6 +33,8 @@ type Devices = { [name: string]: DeviceDescriptor };

export class LocalUtils extends ChannelOwner<channels.LocalUtilsChannel> {
readonly devices: Devices;
private _harBackends = new Map<string, HarBackend>();
private _stackSessions = new Map<string, localUtils.StackSession>();

constructor(parent: ChannelOwner, type: string, guid: string, initializer: channels.LocalUtilsInitializer) {
super(parent, type, guid, initializer);
Expand All@@ -39,4 +43,40 @@ export class LocalUtils extends ChannelOwner<channels.LocalUtilsChannel> {
for (const { name, descriptor } of initializer.deviceDescriptors)
this.devices[name] = descriptor;
}

async zip(params: channels.LocalUtilsZipParams): Promise<void> {
return await localUtils.zip(this._platform, this._stackSessions, params);
}

async harOpen(params: channels.LocalUtilsHarOpenParams): Promise<channels.LocalUtilsHarOpenResult> {
return await localUtils.harOpen(this._harBackends, params);
}

async harLookup(params: channels.LocalUtilsHarLookupParams): Promise<channels.LocalUtilsHarLookupResult> {
return await localUtils.harLookup(this._harBackends, params);
}

async harClose(params: channels.LocalUtilsHarCloseParams): Promise<void> {
return await localUtils.harClose(this._harBackends, params);
}

async harUnzip(params: channels.LocalUtilsHarUnzipParams): Promise<void> {
return await localUtils.harUnzip(params);
}

async tracingStarted(params: channels.LocalUtilsTracingStartedParams): Promise<channels.LocalUtilsTracingStartedResult> {
return await localUtils.tracingStarted(this._stackSessions, params);
}

async traceDiscarded(params: channels.LocalUtilsTraceDiscardedParams): Promise<void> {
return await localUtils.traceDiscarded(this._platform, this._stackSessions, params);
}

async addStackToTracingNoReply(params: channels.LocalUtilsAddStackToTracingNoReplyParams): Promise<void> {
return await localUtils.addStackToTracingNoReply(this._stackSessions, params);
}

async connect(params: channels.LocalUtilsConnectParams): Promise<channels.LocalUtilsConnectResult> {
return await this._channel.connect(params);
}
}
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/selectors.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@
import { ChannelOwner } from './channelOwner';
import { evaluationScript } from './clientHelper';
import { setTestIdAttribute, testIdAttributeName } from './locator';
import { nodePlatform } from '../common/platform';
import { nodePlatform } from '../utils/platform';

import type { SelectorEngine } from './types';
import type * as api from '../../types/types';
Expand Down
10 changes: 5 additions & 5 deletions packages/playwright-core/src/client/tracing.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -69,7 +69,7 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
this._isTracing = true;
this._connection.setIsTracing(true);
}
const result = await this._connection.localUtils()._channel.tracingStarted({ tracesDir: this._tracesDir, traceName });
const result = await this._connection.localUtils().tracingStarted({ tracesDir: this._tracesDir, traceName });
this._stacksId = result.stacksId;
}

Expand All@@ -89,15 +89,15 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
// Not interested in artifacts.
await this._channel.tracingStopChunk({ mode: 'discard' });
if (this._stacksId)
await this._connection.localUtils()._channel.traceDiscarded({ stacksId: this._stacksId });
await this._connection.localUtils().traceDiscarded({ stacksId: this._stacksId });
return;
}

const isLocal = !this._connection.isRemote();

if (isLocal) {
const result = await this._channel.tracingStopChunk({ mode: 'entries' });
await this._connection.localUtils()._channel.zip({ zipFile: filePath, entries: result.entries!, mode: 'write', stacksId: this._stacksId, includeSources: this._includeSources });
await this._connection.localUtils().zip({ zipFile: filePath, entries: result.entries!, mode: 'write', stacksId: this._stacksId, includeSources: this._includeSources });
return;
}

Expand All@@ -106,7 +106,7 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
// The artifact may be missing if the browser closed while stopping tracing.
if (!result.artifact) {
if (this._stacksId)
await this._connection.localUtils()._channel.traceDiscarded({ stacksId: this._stacksId });
await this._connection.localUtils().traceDiscarded({ stacksId: this._stacksId });
return;
}

Expand All@@ -115,7 +115,7 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
await artifact.saveAs(filePath);
await artifact.delete();

await this._connection.localUtils()._channel.zip({ zipFile: filePath, entries: [], mode: 'append', stacksId: this._stacksId, includeSources: this._includeSources });
await this._connection.localUtils().zip({ zipFile: filePath, entries: [], mode: 'append', stacksId: this._stacksId, includeSources: this._includeSources });
}

_resetStackCounter() {
Expand Down
3 changes: 2 additions & 1 deletion packages/playwright-core/src/common/DEPS.list
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
[*]
../utils/
../utilsBundle.ts
../utilsBundle.ts
../zipBundle.ts
23 changes: 23 additions & 0 deletions packages/playwright-core/src/common/progress.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
/**
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

export interface Progress {
log(message: string): void;
timeUntilDeadline(): number;
isRunning(): boolean;
cleanupWhenAborted(cleanup: () => any): void;
throwIfAborted(): void;
}
2 changes: 1 addition & 1 deletion packages/playwright-core/src/inProcessFactory.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -20,8 +20,8 @@ import { Connection } from './client/connection';
import { DispatcherConnection, PlaywrightDispatcher, RootDispatcher, createPlaywright } from './server';

import type { Playwright as PlaywrightAPI } from './client/playwright';
import type { Platform } from './common/platform';
import type { Language } from './utils';
import type { Platform } from './utils/platform';

export function createInProcessPlaywright(platform: Platform): PlaywrightAPI {
const playwright = createPlaywright({ sdkLanguage: (process.env.PW_LANG_NAME as Language | undefined) || 'javascript' });
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/inprocess.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@
* limitations under the License.
*/

import { nodePlatform } from './common/platform';
import { createInProcessPlaywright } from './inProcessFactory';
import { nodePlatform } from './utils/platform';

module.exports = createInProcessPlaywright(nodePlatform);
2 changes: 1 addition & 1 deletion packages/playwright-core/src/outofprocess.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,9 +18,9 @@ import * as childProcess from 'child_process';
import * as path from 'path';

import { Connection } from './client/connection';
import { nodePlatform } from './common/platform';
import { PipeTransport } from './protocol/transport';
import { ManualPromise } from './utils/manualPromise';
import { nodePlatform } from './utils/platform';

import type { Playwright } from './client/playwright';

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' chore: short-cut localUtils usage in JS client by pavelfeldman · Pull Request #34690 · microsoft/playwright · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/playwright-core/src/DEPS.list
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@
**

[inprocess.ts]
common/
utils/

[outofprocess.ts]
client/
Expand Down
4 changes: 2 additions & 2 deletions packages/playwright-core/src/client/android.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,7 +31,7 @@ import type { Page } from './page';
import type * as types from './types';
import type * as api from '../../types/types';
import type { AndroidServerLauncherImpl } from '../androidServerImpl';
import type { Platform } from '../common/platform';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

type Direction = 'down' | 'up' | 'left' | 'right';
Expand DownExpand Up@@ -72,7 +72,7 @@ export class Android extends ChannelOwner<channels.AndroidChannel> implements ap
const headers = { 'x-playwright-browser': 'android', ...options.headers };
const localUtils = this._connection.localUtils();
const connectParams: channels.LocalUtilsConnectParams = { wsEndpoint, headers, slowMo: options.slowMo, timeout: options.timeout };
const { pipe } = await localUtils._channel.connect(connectParams);
const { pipe } = await localUtils.connect(connectParams);
const closePipe = () => pipe.close().catch(() => {});
const connection = new Connection(localUtils, this._platform, this._instrumentation);
connection.markAsRemote();
Expand Down
4 changes: 2 additions & 2 deletions packages/playwright-core/src/client/browserContext.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,8 +45,8 @@ import type { BrowserType } from './browserType';
import type { BrowserContextOptions, Headers, LaunchOptions, StorageState, WaitForEventOptions } from './types';
import type * as structs from '../../types/structs';
import type * as api from '../../types/types';
import type { Platform } from '../common/platform';
import type { URLMatch } from '../utils/isomorphic/urlMatch';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel> implements api.BrowserContext {
Expand DownExpand Up@@ -485,7 +485,7 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel>
const needCompressed = harParams.path.endsWith('.zip');
if (isCompressed && !needCompressed) {
await artifact.saveAs(harParams.path + '.tmp');
await this._connection.localUtils()._channel.harUnzip({ zipFile: harParams.path + '.tmp', harFile: harParams.path });
await this._connection.localUtils().harUnzip({ zipFile: harParams.path + '.tmp', harFile: harParams.path });
} else {
await artifact.saveAs(harParams.path);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/browserType.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -133,7 +133,7 @@ export class BrowserType extends ChannelOwner<channels.BrowserTypeChannel> imple
};
if ((params as any).__testHookRedirectPortForwarding)
connectParams.socksProxyRedirectPortForTest = (params as any).__testHookRedirectPortForwarding;
const { pipe, headers: connectHeaders } = await localUtils._channel.connect(connectParams);
const { pipe, headers: connectHeaders } = await localUtils.connect(connectParams);
const closePipe = () => pipe.close().catch(() => {});
const connection = new Connection(localUtils, this._platform, this._instrumentation);
connection.markAsRemote();
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/channelOwner.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,8 +24,8 @@ import { zones } from '../utils/zones';
import type { ClientInstrumentation } from './clientInstrumentation';
import type { Connection } from './connection';
import type { Logger } from './types';
import type { Platform } from '../common/platform';
import type { ValidatorContext } from '../protocol/validator';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

type Listener = (...args: any[]) => void;
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/clientHelper.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,7 +18,7 @@
import { isString } from '../utils/rtti';

import type * as types from './types';
import type { Platform } from '../common/platform';
import type { Platform } from '../utils/platform';

export function envObjectToArray(env: types.Env): { name: string, value: string }[] {
const result: { name: string, value: string }[] = [];
Expand Down
4 changes: 2 additions & 2 deletions packages/playwright-core/src/client/connection.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -47,8 +47,8 @@ import { formatCallLog, rewriteErrorMessage } from '../utils/stackTrace';
import { zones } from '../utils/zones';

import type { ClientInstrumentation } from './clientInstrumentation';
import type { Platform } from '../common/platform';
import type { ValidatorContext } from '../protocol/validator';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

class Root extends ChannelOwner<channels.RootChannel> {
Expand DownExpand Up@@ -142,7 +142,7 @@ export class Connection extends EventEmitter {
const location = frames[0] ? { file: frames[0].file, line: frames[0].line, column: frames[0].column } : undefined;
const metadata: channels.Metadata = { apiName, location, internal: !apiName, stepId };
if (this._tracingCount && frames && type !== 'LocalUtils')
this._localUtils?._channel.addStackToTracingNoReply({ callData: { stack: frames, id } }).catch(() => {});
this._localUtils?.addStackToTracingNoReply({ callData: { stack: frames, id } }).catch(() => {});
// We need to exit zones before calling into the server, otherwise
// when we receive events from the server, we would be in an API zone.
zones.empty().run(() => this.onmessage({ ...message, metadata }));
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/consoleMessage.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,7 +18,7 @@ import { JSHandle } from './jsHandle';
import { Page } from './page';

import type * as api from '../../types/types';
import type { Platform } from '../common/platform';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

type ConsoleMessageLocation = channels.BrowserContextConsoleEvent['location'];
Expand Down
9 changes: 5 additions & 4 deletions packages/playwright-core/src/client/elementHandle.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,7 +31,7 @@ import type { Locator } from './locator';
import type { FilePayload, Rect, SelectOption, SelectOptionOptions } from './types';
import type * as structs from '../../types/structs';
import type * as api from '../../types/types';
import type { Platform } from '../common/platform';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

const pipelineAsync = promisify(pipeline);
Expand DownExpand Up@@ -192,12 +192,13 @@ export class ElementHandle<T extends Node = Node> extends JSHandle<T> implements
return value === undefined ? null : value;
}

async screenshot(options: Omit<channels.ElementHandleScreenshotOptions, 'mask'> & { path?: string, mask?: Locator[] } = {}): Promise<Buffer> {
async screenshot(options: Omit<channels.ElementHandleScreenshotOptions, 'mask'> & { path?: string, mask?: api.Locator[] } = {}): Promise<Buffer> {
const mask = options.mask as Locator[] | undefined;
const copy: channels.ElementHandleScreenshotOptions = { ...options, mask: undefined };
if (!copy.type)
copy.type = determineScreenshotType(options);
if (options.mask) {
copy.mask = options.mask.map(locator => ({
if (mask) {
copy.mask = mask.map(locator => ({
frame: locator._frame._channel,
selector: locator._selector,
}));
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/fetch.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -28,8 +28,8 @@ import type { Playwright } from './playwright';
import type { ClientCertificate, FilePayload, Headers, SetStorageState, StorageState } from './types';
import type { Serializable } from '../../types/structs';
import type * as api from '../../types/types';
import type { Platform } from '../common/platform';
import type { HeadersArray, NameValue } from '../common/types';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';
import type * as fs from 'fs';

Expand Down
6 changes: 3 additions & 3 deletions packages/playwright-core/src/client/harRouter.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,7 +31,7 @@ export class HarRouter {
private _options: { urlMatch?: URLMatch; baseURL?: string; };

static async create(localUtils: LocalUtils, file: string, notFoundAction: HarNotFoundAction, options: { urlMatch?: URLMatch }): Promise<HarRouter> {
const { harId, error } = await localUtils._channel.harOpen({ file });
const { harId, error } = await localUtils.harOpen({ file });
if (error)
throw new Error(error);
return new HarRouter(localUtils, harId!, notFoundAction, options);
Expand All@@ -47,7 +47,7 @@ export class HarRouter {
private async _handle(route: Route) {
const request = route.request();

const response = await this._localUtils._channel.harLookup({
const response = await this._localUtils.harLookup({
harId: this._harId,
url: request.url(),
method: request.method(),
Expand DownExpand Up@@ -103,6 +103,6 @@ export class HarRouter {
}

dispose() {
this._localUtils._channel.harClose({ harId: this._harId }).catch(() => {});
this._localUtils.harClose({ harId: this._harId }).catch(() => {});
}
}
40 changes: 40 additions & 0 deletions packages/playwright-core/src/client/localUtils.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,8 +15,10 @@
*/

import { ChannelOwner } from './channelOwner';
import * as localUtils from '../utils/localUtils';

import type { Size } from './types';
import type { HarBackend } from '../utils/harBackend';
import type * as channels from '@protocol/channels';

type DeviceDescriptor = {
Expand All@@ -31,6 +33,8 @@ type Devices = { [name: string]: DeviceDescriptor };

export class LocalUtils extends ChannelOwner<channels.LocalUtilsChannel> {
readonly devices: Devices;
private _harBackends = new Map<string, HarBackend>();
private _stackSessions = new Map<string, localUtils.StackSession>();

constructor(parent: ChannelOwner, type: string, guid: string, initializer: channels.LocalUtilsInitializer) {
super(parent, type, guid, initializer);
Expand All@@ -39,4 +43,40 @@ export class LocalUtils extends ChannelOwner<channels.LocalUtilsChannel> {
for (const { name, descriptor } of initializer.deviceDescriptors)
this.devices[name] = descriptor;
}

async zip(params: channels.LocalUtilsZipParams): Promise<void> {
return await localUtils.zip(this._platform, this._stackSessions, params);
}

async harOpen(params: channels.LocalUtilsHarOpenParams): Promise<channels.LocalUtilsHarOpenResult> {
return await localUtils.harOpen(this._harBackends, params);
}

async harLookup(params: channels.LocalUtilsHarLookupParams): Promise<channels.LocalUtilsHarLookupResult> {
return await localUtils.harLookup(this._harBackends, params);
}

async harClose(params: channels.LocalUtilsHarCloseParams): Promise<void> {
return await localUtils.harClose(this._harBackends, params);
}

async harUnzip(params: channels.LocalUtilsHarUnzipParams): Promise<void> {
return await localUtils.harUnzip(params);
}

async tracingStarted(params: channels.LocalUtilsTracingStartedParams): Promise<channels.LocalUtilsTracingStartedResult> {
return await localUtils.tracingStarted(this._stackSessions, params);
}

async traceDiscarded(params: channels.LocalUtilsTraceDiscardedParams): Promise<void> {
return await localUtils.traceDiscarded(this._platform, this._stackSessions, params);
}

async addStackToTracingNoReply(params: channels.LocalUtilsAddStackToTracingNoReplyParams): Promise<void> {
return await localUtils.addStackToTracingNoReply(this._stackSessions, params);
}

async connect(params: channels.LocalUtilsConnectParams): Promise<channels.LocalUtilsConnectResult> {
return await this._channel.connect(params);
}
}
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/selectors.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@
import { ChannelOwner } from './channelOwner';
import { evaluationScript } from './clientHelper';
import { setTestIdAttribute, testIdAttributeName } from './locator';
import { nodePlatform } from '../common/platform';
import { nodePlatform } from '../utils/platform';

import type { SelectorEngine } from './types';
import type * as api from '../../types/types';
Expand Down
10 changes: 5 additions & 5 deletions packages/playwright-core/src/client/tracing.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -69,7 +69,7 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
this._isTracing = true;
this._connection.setIsTracing(true);
}
const result = await this._connection.localUtils()._channel.tracingStarted({ tracesDir: this._tracesDir, traceName });
const result = await this._connection.localUtils().tracingStarted({ tracesDir: this._tracesDir, traceName });
this._stacksId = result.stacksId;
}

Expand All@@ -89,15 +89,15 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
// Not interested in artifacts.
await this._channel.tracingStopChunk({ mode: 'discard' });
if (this._stacksId)
await this._connection.localUtils()._channel.traceDiscarded({ stacksId: this._stacksId });
await this._connection.localUtils().traceDiscarded({ stacksId: this._stacksId });
return;
}

const isLocal = !this._connection.isRemote();

if (isLocal) {
const result = await this._channel.tracingStopChunk({ mode: 'entries' });
await this._connection.localUtils()._channel.zip({ zipFile: filePath, entries: result.entries!, mode: 'write', stacksId: this._stacksId, includeSources: this._includeSources });
await this._connection.localUtils().zip({ zipFile: filePath, entries: result.entries!, mode: 'write', stacksId: this._stacksId, includeSources: this._includeSources });
return;
}

Expand All@@ -106,7 +106,7 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
// The artifact may be missing if the browser closed while stopping tracing.
if (!result.artifact) {
if (this._stacksId)
await this._connection.localUtils()._channel.traceDiscarded({ stacksId: this._stacksId });
await this._connection.localUtils().traceDiscarded({ stacksId: this._stacksId });
return;
}

Expand All@@ -115,7 +115,7 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
await artifact.saveAs(filePath);
await artifact.delete();

await this._connection.localUtils()._channel.zip({ zipFile: filePath, entries: [], mode: 'append', stacksId: this._stacksId, includeSources: this._includeSources });
await this._connection.localUtils().zip({ zipFile: filePath, entries: [], mode: 'append', stacksId: this._stacksId, includeSources: this._includeSources });
}

_resetStackCounter() {
Expand Down
3 changes: 2 additions & 1 deletion packages/playwright-core/src/common/DEPS.list
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
[*]
../utils/
../utilsBundle.ts
../utilsBundle.ts
../zipBundle.ts
23 changes: 23 additions & 0 deletions packages/playwright-core/src/common/progress.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
/**
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

export interface Progress {
log(message: string): void;
timeUntilDeadline(): number;
isRunning(): boolean;
cleanupWhenAborted(cleanup: () => any): void;
throwIfAborted(): void;
}
2 changes: 1 addition & 1 deletion packages/playwright-core/src/inProcessFactory.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -20,8 +20,8 @@ import { Connection } from './client/connection';
import { DispatcherConnection, PlaywrightDispatcher, RootDispatcher, createPlaywright } from './server';

import type { Playwright as PlaywrightAPI } from './client/playwright';
import type { Platform } from './common/platform';
import type { Language } from './utils';
import type { Platform } from './utils/platform';

export function createInProcessPlaywright(platform: Platform): PlaywrightAPI {
const playwright = createPlaywright({ sdkLanguage: (process.env.PW_LANG_NAME as Language | undefined) || 'javascript' });
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/inprocess.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@
* limitations under the License.
*/

import { nodePlatform } from './common/platform';
import { createInProcessPlaywright } from './inProcessFactory';
import { nodePlatform } from './utils/platform';

module.exports = createInProcessPlaywright(nodePlatform);
2 changes: 1 addition & 1 deletion packages/playwright-core/src/outofprocess.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,9 +18,9 @@ import * as childProcess from 'child_process';
import * as path from 'path';

import { Connection } from './client/connection';
import { nodePlatform } from './common/platform';
import { PipeTransport } from './protocol/transport';
import { ManualPromise } from './utils/manualPromise';
import { nodePlatform } from './utils/platform';

import type { Playwright } from './client/playwright';

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' chore: short-cut localUtils usage in JS client by pavelfeldman · Pull Request #34690 · microsoft/playwright · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/playwright-core/src/DEPS.list
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@
**

[inprocess.ts]
common/
utils/

[outofprocess.ts]
client/
Expand Down
4 changes: 2 additions & 2 deletions packages/playwright-core/src/client/android.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,7 +31,7 @@ import type { Page } from './page';
import type * as types from './types';
import type * as api from '../../types/types';
import type { AndroidServerLauncherImpl } from '../androidServerImpl';
import type { Platform } from '../common/platform';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

type Direction = 'down' | 'up' | 'left' | 'right';
Expand DownExpand Up@@ -72,7 +72,7 @@ export class Android extends ChannelOwner<channels.AndroidChannel> implements ap
const headers = { 'x-playwright-browser': 'android', ...options.headers };
const localUtils = this._connection.localUtils();
const connectParams: channels.LocalUtilsConnectParams = { wsEndpoint, headers, slowMo: options.slowMo, timeout: options.timeout };
const { pipe } = await localUtils._channel.connect(connectParams);
const { pipe } = await localUtils.connect(connectParams);
const closePipe = () => pipe.close().catch(() => {});
const connection = new Connection(localUtils, this._platform, this._instrumentation);
connection.markAsRemote();
Expand Down
4 changes: 2 additions & 2 deletions packages/playwright-core/src/client/browserContext.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,8 +45,8 @@ import type { BrowserType } from './browserType';
import type { BrowserContextOptions, Headers, LaunchOptions, StorageState, WaitForEventOptions } from './types';
import type * as structs from '../../types/structs';
import type * as api from '../../types/types';
import type { Platform } from '../common/platform';
import type { URLMatch } from '../utils/isomorphic/urlMatch';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel> implements api.BrowserContext {
Expand DownExpand Up@@ -485,7 +485,7 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel>
const needCompressed = harParams.path.endsWith('.zip');
if (isCompressed && !needCompressed) {
await artifact.saveAs(harParams.path + '.tmp');
await this._connection.localUtils()._channel.harUnzip({ zipFile: harParams.path + '.tmp', harFile: harParams.path });
await this._connection.localUtils().harUnzip({ zipFile: harParams.path + '.tmp', harFile: harParams.path });
} else {
await artifact.saveAs(harParams.path);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/browserType.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -133,7 +133,7 @@ export class BrowserType extends ChannelOwner<channels.BrowserTypeChannel> imple
};
if ((params as any).__testHookRedirectPortForwarding)
connectParams.socksProxyRedirectPortForTest = (params as any).__testHookRedirectPortForwarding;
const { pipe, headers: connectHeaders } = await localUtils._channel.connect(connectParams);
const { pipe, headers: connectHeaders } = await localUtils.connect(connectParams);
const closePipe = () => pipe.close().catch(() => {});
const connection = new Connection(localUtils, this._platform, this._instrumentation);
connection.markAsRemote();
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/channelOwner.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,8 +24,8 @@ import { zones } from '../utils/zones';
import type { ClientInstrumentation } from './clientInstrumentation';
import type { Connection } from './connection';
import type { Logger } from './types';
import type { Platform } from '../common/platform';
import type { ValidatorContext } from '../protocol/validator';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

type Listener = (...args: any[]) => void;
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/clientHelper.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,7 +18,7 @@
import { isString } from '../utils/rtti';

import type * as types from './types';
import type { Platform } from '../common/platform';
import type { Platform } from '../utils/platform';

export function envObjectToArray(env: types.Env): { name: string, value: string }[] {
const result: { name: string, value: string }[] = [];
Expand Down
4 changes: 2 additions & 2 deletions packages/playwright-core/src/client/connection.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -47,8 +47,8 @@ import { formatCallLog, rewriteErrorMessage } from '../utils/stackTrace';
import { zones } from '../utils/zones';

import type { ClientInstrumentation } from './clientInstrumentation';
import type { Platform } from '../common/platform';
import type { ValidatorContext } from '../protocol/validator';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

class Root extends ChannelOwner<channels.RootChannel> {
Expand DownExpand Up@@ -142,7 +142,7 @@ export class Connection extends EventEmitter {
const location = frames[0] ? { file: frames[0].file, line: frames[0].line, column: frames[0].column } : undefined;
const metadata: channels.Metadata = { apiName, location, internal: !apiName, stepId };
if (this._tracingCount && frames && type !== 'LocalUtils')
this._localUtils?._channel.addStackToTracingNoReply({ callData: { stack: frames, id } }).catch(() => {});
this._localUtils?.addStackToTracingNoReply({ callData: { stack: frames, id } }).catch(() => {});
// We need to exit zones before calling into the server, otherwise
// when we receive events from the server, we would be in an API zone.
zones.empty().run(() => this.onmessage({ ...message, metadata }));
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/consoleMessage.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,7 +18,7 @@ import { JSHandle } from './jsHandle';
import { Page } from './page';

import type * as api from '../../types/types';
import type { Platform } from '../common/platform';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

type ConsoleMessageLocation = channels.BrowserContextConsoleEvent['location'];
Expand Down
9 changes: 5 additions & 4 deletions packages/playwright-core/src/client/elementHandle.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,7 +31,7 @@ import type { Locator } from './locator';
import type { FilePayload, Rect, SelectOption, SelectOptionOptions } from './types';
import type * as structs from '../../types/structs';
import type * as api from '../../types/types';
import type { Platform } from '../common/platform';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

const pipelineAsync = promisify(pipeline);
Expand DownExpand Up@@ -192,12 +192,13 @@ export class ElementHandle<T extends Node = Node> extends JSHandle<T> implements
return value === undefined ? null : value;
}

async screenshot(options: Omit<channels.ElementHandleScreenshotOptions, 'mask'> & { path?: string, mask?: Locator[] } = {}): Promise<Buffer> {
async screenshot(options: Omit<channels.ElementHandleScreenshotOptions, 'mask'> & { path?: string, mask?: api.Locator[] } = {}): Promise<Buffer> {
const mask = options.mask as Locator[] | undefined;
const copy: channels.ElementHandleScreenshotOptions = { ...options, mask: undefined };
if (!copy.type)
copy.type = determineScreenshotType(options);
if (options.mask) {
copy.mask = options.mask.map(locator => ({
if (mask) {
copy.mask = mask.map(locator => ({
frame: locator._frame._channel,
selector: locator._selector,
}));
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/fetch.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -28,8 +28,8 @@ import type { Playwright } from './playwright';
import type { ClientCertificate, FilePayload, Headers, SetStorageState, StorageState } from './types';
import type { Serializable } from '../../types/structs';
import type * as api from '../../types/types';
import type { Platform } from '../common/platform';
import type { HeadersArray, NameValue } from '../common/types';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';
import type * as fs from 'fs';

Expand Down
6 changes: 3 additions & 3 deletions packages/playwright-core/src/client/harRouter.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,7 +31,7 @@ export class HarRouter {
private _options: { urlMatch?: URLMatch; baseURL?: string; };

static async create(localUtils: LocalUtils, file: string, notFoundAction: HarNotFoundAction, options: { urlMatch?: URLMatch }): Promise<HarRouter> {
const { harId, error } = await localUtils._channel.harOpen({ file });
const { harId, error } = await localUtils.harOpen({ file });
if (error)
throw new Error(error);
return new HarRouter(localUtils, harId!, notFoundAction, options);
Expand All@@ -47,7 +47,7 @@ export class HarRouter {
private async _handle(route: Route) {
const request = route.request();

const response = await this._localUtils._channel.harLookup({
const response = await this._localUtils.harLookup({
harId: this._harId,
url: request.url(),
method: request.method(),
Expand DownExpand Up@@ -103,6 +103,6 @@ export class HarRouter {
}

dispose() {
this._localUtils._channel.harClose({ harId: this._harId }).catch(() => {});
this._localUtils.harClose({ harId: this._harId }).catch(() => {});
}
}
40 changes: 40 additions & 0 deletions packages/playwright-core/src/client/localUtils.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,8 +15,10 @@
*/

import { ChannelOwner } from './channelOwner';
import * as localUtils from '../utils/localUtils';

import type { Size } from './types';
import type { HarBackend } from '../utils/harBackend';
import type * as channels from '@protocol/channels';

type DeviceDescriptor = {
Expand All@@ -31,6 +33,8 @@ type Devices = { [name: string]: DeviceDescriptor };

export class LocalUtils extends ChannelOwner<channels.LocalUtilsChannel> {
readonly devices: Devices;
private _harBackends = new Map<string, HarBackend>();
private _stackSessions = new Map<string, localUtils.StackSession>();

constructor(parent: ChannelOwner, type: string, guid: string, initializer: channels.LocalUtilsInitializer) {
super(parent, type, guid, initializer);
Expand All@@ -39,4 +43,40 @@ export class LocalUtils extends ChannelOwner<channels.LocalUtilsChannel> {
for (const { name, descriptor } of initializer.deviceDescriptors)
this.devices[name] = descriptor;
}

async zip(params: channels.LocalUtilsZipParams): Promise<void> {
return await localUtils.zip(this._platform, this._stackSessions, params);
}

async harOpen(params: channels.LocalUtilsHarOpenParams): Promise<channels.LocalUtilsHarOpenResult> {
return await localUtils.harOpen(this._harBackends, params);
}

async harLookup(params: channels.LocalUtilsHarLookupParams): Promise<channels.LocalUtilsHarLookupResult> {
return await localUtils.harLookup(this._harBackends, params);
}

async harClose(params: channels.LocalUtilsHarCloseParams): Promise<void> {
return await localUtils.harClose(this._harBackends, params);
}

async harUnzip(params: channels.LocalUtilsHarUnzipParams): Promise<void> {
return await localUtils.harUnzip(params);
}

async tracingStarted(params: channels.LocalUtilsTracingStartedParams): Promise<channels.LocalUtilsTracingStartedResult> {
return await localUtils.tracingStarted(this._stackSessions, params);
}

async traceDiscarded(params: channels.LocalUtilsTraceDiscardedParams): Promise<void> {
return await localUtils.traceDiscarded(this._platform, this._stackSessions, params);
}

async addStackToTracingNoReply(params: channels.LocalUtilsAddStackToTracingNoReplyParams): Promise<void> {
return await localUtils.addStackToTracingNoReply(this._stackSessions, params);
}

async connect(params: channels.LocalUtilsConnectParams): Promise<channels.LocalUtilsConnectResult> {
return await this._channel.connect(params);
}
}
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/selectors.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@
import { ChannelOwner } from './channelOwner';
import { evaluationScript } from './clientHelper';
import { setTestIdAttribute, testIdAttributeName } from './locator';
import { nodePlatform } from '../common/platform';
import { nodePlatform } from '../utils/platform';

import type { SelectorEngine } from './types';
import type * as api from '../../types/types';
Expand Down
10 changes: 5 additions & 5 deletions packages/playwright-core/src/client/tracing.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -69,7 +69,7 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
this._isTracing = true;
this._connection.setIsTracing(true);
}
const result = await this._connection.localUtils()._channel.tracingStarted({ tracesDir: this._tracesDir, traceName });
const result = await this._connection.localUtils().tracingStarted({ tracesDir: this._tracesDir, traceName });
this._stacksId = result.stacksId;
}

Expand All@@ -89,15 +89,15 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
// Not interested in artifacts.
await this._channel.tracingStopChunk({ mode: 'discard' });
if (this._stacksId)
await this._connection.localUtils()._channel.traceDiscarded({ stacksId: this._stacksId });
await this._connection.localUtils().traceDiscarded({ stacksId: this._stacksId });
return;
}

const isLocal = !this._connection.isRemote();

if (isLocal) {
const result = await this._channel.tracingStopChunk({ mode: 'entries' });
await this._connection.localUtils()._channel.zip({ zipFile: filePath, entries: result.entries!, mode: 'write', stacksId: this._stacksId, includeSources: this._includeSources });
await this._connection.localUtils().zip({ zipFile: filePath, entries: result.entries!, mode: 'write', stacksId: this._stacksId, includeSources: this._includeSources });
return;
}

Expand All@@ -106,7 +106,7 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
// The artifact may be missing if the browser closed while stopping tracing.
if (!result.artifact) {
if (this._stacksId)
await this._connection.localUtils()._channel.traceDiscarded({ stacksId: this._stacksId });
await this._connection.localUtils().traceDiscarded({ stacksId: this._stacksId });
return;
}

Expand All@@ -115,7 +115,7 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
await artifact.saveAs(filePath);
await artifact.delete();

await this._connection.localUtils()._channel.zip({ zipFile: filePath, entries: [], mode: 'append', stacksId: this._stacksId, includeSources: this._includeSources });
await this._connection.localUtils().zip({ zipFile: filePath, entries: [], mode: 'append', stacksId: this._stacksId, includeSources: this._includeSources });
}

_resetStackCounter() {
Expand Down
3 changes: 2 additions & 1 deletion packages/playwright-core/src/common/DEPS.list
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
[*]
../utils/
../utilsBundle.ts
../utilsBundle.ts
../zipBundle.ts
23 changes: 23 additions & 0 deletions packages/playwright-core/src/common/progress.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
/**
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

export interface Progress {
log(message: string): void;
timeUntilDeadline(): number;
isRunning(): boolean;
cleanupWhenAborted(cleanup: () => any): void;
throwIfAborted(): void;
}
2 changes: 1 addition & 1 deletion packages/playwright-core/src/inProcessFactory.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -20,8 +20,8 @@ import { Connection } from './client/connection';
import { DispatcherConnection, PlaywrightDispatcher, RootDispatcher, createPlaywright } from './server';

import type { Playwright as PlaywrightAPI } from './client/playwright';
import type { Platform } from './common/platform';
import type { Language } from './utils';
import type { Platform } from './utils/platform';

export function createInProcessPlaywright(platform: Platform): PlaywrightAPI {
const playwright = createPlaywright({ sdkLanguage: (process.env.PW_LANG_NAME as Language | undefined) || 'javascript' });
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/inprocess.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@
* limitations under the License.
*/

import { nodePlatform } from './common/platform';
import { createInProcessPlaywright } from './inProcessFactory';
import { nodePlatform } from './utils/platform';

module.exports = createInProcessPlaywright(nodePlatform);
2 changes: 1 addition & 1 deletion packages/playwright-core/src/outofprocess.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,9 +18,9 @@ import * as childProcess from 'child_process';
import * as path from 'path';

import { Connection } from './client/connection';
import { nodePlatform } from './common/platform';
import { PipeTransport } from './protocol/transport';
import { ManualPromise } from './utils/manualPromise';
import { nodePlatform } from './utils/platform';

import type { Playwright } from './client/playwright';

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' chore: short-cut localUtils usage in JS client by pavelfeldman · Pull Request #34690 · microsoft/playwright · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/playwright-core/src/DEPS.list
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@
**

[inprocess.ts]
common/
utils/

[outofprocess.ts]
client/
Expand Down
4 changes: 2 additions & 2 deletions packages/playwright-core/src/client/android.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,7 +31,7 @@ import type { Page } from './page';
import type * as types from './types';
import type * as api from '../../types/types';
import type { AndroidServerLauncherImpl } from '../androidServerImpl';
import type { Platform } from '../common/platform';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

type Direction = 'down' | 'up' | 'left' | 'right';
Expand DownExpand Up@@ -72,7 +72,7 @@ export class Android extends ChannelOwner<channels.AndroidChannel> implements ap
const headers = { 'x-playwright-browser': 'android', ...options.headers };
const localUtils = this._connection.localUtils();
const connectParams: channels.LocalUtilsConnectParams = { wsEndpoint, headers, slowMo: options.slowMo, timeout: options.timeout };
const { pipe } = await localUtils._channel.connect(connectParams);
const { pipe } = await localUtils.connect(connectParams);
const closePipe = () => pipe.close().catch(() => {});
const connection = new Connection(localUtils, this._platform, this._instrumentation);
connection.markAsRemote();
Expand Down
4 changes: 2 additions & 2 deletions packages/playwright-core/src/client/browserContext.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,8 +45,8 @@ import type { BrowserType } from './browserType';
import type { BrowserContextOptions, Headers, LaunchOptions, StorageState, WaitForEventOptions } from './types';
import type * as structs from '../../types/structs';
import type * as api from '../../types/types';
import type { Platform } from '../common/platform';
import type { URLMatch } from '../utils/isomorphic/urlMatch';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel> implements api.BrowserContext {
Expand DownExpand Up@@ -485,7 +485,7 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel>
const needCompressed = harParams.path.endsWith('.zip');
if (isCompressed && !needCompressed) {
await artifact.saveAs(harParams.path + '.tmp');
await this._connection.localUtils()._channel.harUnzip({ zipFile: harParams.path + '.tmp', harFile: harParams.path });
await this._connection.localUtils().harUnzip({ zipFile: harParams.path + '.tmp', harFile: harParams.path });
} else {
await artifact.saveAs(harParams.path);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/browserType.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -133,7 +133,7 @@ export class BrowserType extends ChannelOwner<channels.BrowserTypeChannel> imple
};
if ((params as any).__testHookRedirectPortForwarding)
connectParams.socksProxyRedirectPortForTest = (params as any).__testHookRedirectPortForwarding;
const { pipe, headers: connectHeaders } = await localUtils._channel.connect(connectParams);
const { pipe, headers: connectHeaders } = await localUtils.connect(connectParams);
const closePipe = () => pipe.close().catch(() => {});
const connection = new Connection(localUtils, this._platform, this._instrumentation);
connection.markAsRemote();
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/channelOwner.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,8 +24,8 @@ import { zones } from '../utils/zones';
import type { ClientInstrumentation } from './clientInstrumentation';
import type { Connection } from './connection';
import type { Logger } from './types';
import type { Platform } from '../common/platform';
import type { ValidatorContext } from '../protocol/validator';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

type Listener = (...args: any[]) => void;
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/clientHelper.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,7 +18,7 @@
import { isString } from '../utils/rtti';

import type * as types from './types';
import type { Platform } from '../common/platform';
import type { Platform } from '../utils/platform';

export function envObjectToArray(env: types.Env): { name: string, value: string }[] {
const result: { name: string, value: string }[] = [];
Expand Down
4 changes: 2 additions & 2 deletions packages/playwright-core/src/client/connection.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -47,8 +47,8 @@ import { formatCallLog, rewriteErrorMessage } from '../utils/stackTrace';
import { zones } from '../utils/zones';

import type { ClientInstrumentation } from './clientInstrumentation';
import type { Platform } from '../common/platform';
import type { ValidatorContext } from '../protocol/validator';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

class Root extends ChannelOwner<channels.RootChannel> {
Expand DownExpand Up@@ -142,7 +142,7 @@ export class Connection extends EventEmitter {
const location = frames[0] ? { file: frames[0].file, line: frames[0].line, column: frames[0].column } : undefined;
const metadata: channels.Metadata = { apiName, location, internal: !apiName, stepId };
if (this._tracingCount && frames && type !== 'LocalUtils')
this._localUtils?._channel.addStackToTracingNoReply({ callData: { stack: frames, id } }).catch(() => {});
this._localUtils?.addStackToTracingNoReply({ callData: { stack: frames, id } }).catch(() => {});
// We need to exit zones before calling into the server, otherwise
// when we receive events from the server, we would be in an API zone.
zones.empty().run(() => this.onmessage({ ...message, metadata }));
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/consoleMessage.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,7 +18,7 @@ import { JSHandle } from './jsHandle';
import { Page } from './page';

import type * as api from '../../types/types';
import type { Platform } from '../common/platform';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

type ConsoleMessageLocation = channels.BrowserContextConsoleEvent['location'];
Expand Down
9 changes: 5 additions & 4 deletions packages/playwright-core/src/client/elementHandle.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,7 +31,7 @@ import type { Locator } from './locator';
import type { FilePayload, Rect, SelectOption, SelectOptionOptions } from './types';
import type * as structs from '../../types/structs';
import type * as api from '../../types/types';
import type { Platform } from '../common/platform';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

const pipelineAsync = promisify(pipeline);
Expand DownExpand Up@@ -192,12 +192,13 @@ export class ElementHandle<T extends Node = Node> extends JSHandle<T> implements
return value === undefined ? null : value;
}

async screenshot(options: Omit<channels.ElementHandleScreenshotOptions, 'mask'> & { path?: string, mask?: Locator[] } = {}): Promise<Buffer> {
async screenshot(options: Omit<channels.ElementHandleScreenshotOptions, 'mask'> & { path?: string, mask?: api.Locator[] } = {}): Promise<Buffer> {
const mask = options.mask as Locator[] | undefined;
const copy: channels.ElementHandleScreenshotOptions = { ...options, mask: undefined };
if (!copy.type)
copy.type = determineScreenshotType(options);
if (options.mask) {
copy.mask = options.mask.map(locator => ({
if (mask) {
copy.mask = mask.map(locator => ({
frame: locator._frame._channel,
selector: locator._selector,
}));
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/fetch.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -28,8 +28,8 @@ import type { Playwright } from './playwright';
import type { ClientCertificate, FilePayload, Headers, SetStorageState, StorageState } from './types';
import type { Serializable } from '../../types/structs';
import type * as api from '../../types/types';
import type { Platform } from '../common/platform';
import type { HeadersArray, NameValue } from '../common/types';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';
import type * as fs from 'fs';

Expand Down
6 changes: 3 additions & 3 deletions packages/playwright-core/src/client/harRouter.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,7 +31,7 @@ export class HarRouter {
private _options: { urlMatch?: URLMatch; baseURL?: string; };

static async create(localUtils: LocalUtils, file: string, notFoundAction: HarNotFoundAction, options: { urlMatch?: URLMatch }): Promise<HarRouter> {
const { harId, error } = await localUtils._channel.harOpen({ file });
const { harId, error } = await localUtils.harOpen({ file });
if (error)
throw new Error(error);
return new HarRouter(localUtils, harId!, notFoundAction, options);
Expand All@@ -47,7 +47,7 @@ export class HarRouter {
private async _handle(route: Route) {
const request = route.request();

const response = await this._localUtils._channel.harLookup({
const response = await this._localUtils.harLookup({
harId: this._harId,
url: request.url(),
method: request.method(),
Expand DownExpand Up@@ -103,6 +103,6 @@ export class HarRouter {
}

dispose() {
this._localUtils._channel.harClose({ harId: this._harId }).catch(() => {});
this._localUtils.harClose({ harId: this._harId }).catch(() => {});
}
}
40 changes: 40 additions & 0 deletions packages/playwright-core/src/client/localUtils.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,8 +15,10 @@
*/

import { ChannelOwner } from './channelOwner';
import * as localUtils from '../utils/localUtils';

import type { Size } from './types';
import type { HarBackend } from '../utils/harBackend';
import type * as channels from '@protocol/channels';

type DeviceDescriptor = {
Expand All@@ -31,6 +33,8 @@ type Devices = { [name: string]: DeviceDescriptor };

export class LocalUtils extends ChannelOwner<channels.LocalUtilsChannel> {
readonly devices: Devices;
private _harBackends = new Map<string, HarBackend>();
private _stackSessions = new Map<string, localUtils.StackSession>();

constructor(parent: ChannelOwner, type: string, guid: string, initializer: channels.LocalUtilsInitializer) {
super(parent, type, guid, initializer);
Expand All@@ -39,4 +43,40 @@ export class LocalUtils extends ChannelOwner<channels.LocalUtilsChannel> {
for (const { name, descriptor } of initializer.deviceDescriptors)
this.devices[name] = descriptor;
}

async zip(params: channels.LocalUtilsZipParams): Promise<void> {
return await localUtils.zip(this._platform, this._stackSessions, params);
}

async harOpen(params: channels.LocalUtilsHarOpenParams): Promise<channels.LocalUtilsHarOpenResult> {
return await localUtils.harOpen(this._harBackends, params);
}

async harLookup(params: channels.LocalUtilsHarLookupParams): Promise<channels.LocalUtilsHarLookupResult> {
return await localUtils.harLookup(this._harBackends, params);
}

async harClose(params: channels.LocalUtilsHarCloseParams): Promise<void> {
return await localUtils.harClose(this._harBackends, params);
}

async harUnzip(params: channels.LocalUtilsHarUnzipParams): Promise<void> {
return await localUtils.harUnzip(params);
}

async tracingStarted(params: channels.LocalUtilsTracingStartedParams): Promise<channels.LocalUtilsTracingStartedResult> {
return await localUtils.tracingStarted(this._stackSessions, params);
}

async traceDiscarded(params: channels.LocalUtilsTraceDiscardedParams): Promise<void> {
return await localUtils.traceDiscarded(this._platform, this._stackSessions, params);
}

async addStackToTracingNoReply(params: channels.LocalUtilsAddStackToTracingNoReplyParams): Promise<void> {
return await localUtils.addStackToTracingNoReply(this._stackSessions, params);
}

async connect(params: channels.LocalUtilsConnectParams): Promise<channels.LocalUtilsConnectResult> {
return await this._channel.connect(params);
}
}
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/selectors.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@
import { ChannelOwner } from './channelOwner';
import { evaluationScript } from './clientHelper';
import { setTestIdAttribute, testIdAttributeName } from './locator';
import { nodePlatform } from '../common/platform';
import { nodePlatform } from '../utils/platform';

import type { SelectorEngine } from './types';
import type * as api from '../../types/types';
Expand Down
10 changes: 5 additions & 5 deletions packages/playwright-core/src/client/tracing.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -69,7 +69,7 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
this._isTracing = true;
this._connection.setIsTracing(true);
}
const result = await this._connection.localUtils()._channel.tracingStarted({ tracesDir: this._tracesDir, traceName });
const result = await this._connection.localUtils().tracingStarted({ tracesDir: this._tracesDir, traceName });
this._stacksId = result.stacksId;
}

Expand All@@ -89,15 +89,15 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
// Not interested in artifacts.
await this._channel.tracingStopChunk({ mode: 'discard' });
if (this._stacksId)
await this._connection.localUtils()._channel.traceDiscarded({ stacksId: this._stacksId });
await this._connection.localUtils().traceDiscarded({ stacksId: this._stacksId });
return;
}

const isLocal = !this._connection.isRemote();

if (isLocal) {
const result = await this._channel.tracingStopChunk({ mode: 'entries' });
await this._connection.localUtils()._channel.zip({ zipFile: filePath, entries: result.entries!, mode: 'write', stacksId: this._stacksId, includeSources: this._includeSources });
await this._connection.localUtils().zip({ zipFile: filePath, entries: result.entries!, mode: 'write', stacksId: this._stacksId, includeSources: this._includeSources });
return;
}

Expand All@@ -106,7 +106,7 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
// The artifact may be missing if the browser closed while stopping tracing.
if (!result.artifact) {
if (this._stacksId)
await this._connection.localUtils()._channel.traceDiscarded({ stacksId: this._stacksId });
await this._connection.localUtils().traceDiscarded({ stacksId: this._stacksId });
return;
}

Expand All@@ -115,7 +115,7 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
await artifact.saveAs(filePath);
await artifact.delete();

await this._connection.localUtils()._channel.zip({ zipFile: filePath, entries: [], mode: 'append', stacksId: this._stacksId, includeSources: this._includeSources });
await this._connection.localUtils().zip({ zipFile: filePath, entries: [], mode: 'append', stacksId: this._stacksId, includeSources: this._includeSources });
}

_resetStackCounter() {
Expand Down
3 changes: 2 additions & 1 deletion packages/playwright-core/src/common/DEPS.list
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
[*]
../utils/
../utilsBundle.ts
../utilsBundle.ts
../zipBundle.ts
23 changes: 23 additions & 0 deletions packages/playwright-core/src/common/progress.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
/**
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

export interface Progress {
log(message: string): void;
timeUntilDeadline(): number;
isRunning(): boolean;
cleanupWhenAborted(cleanup: () => any): void;
throwIfAborted(): void;
}
2 changes: 1 addition & 1 deletion packages/playwright-core/src/inProcessFactory.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -20,8 +20,8 @@ import { Connection } from './client/connection';
import { DispatcherConnection, PlaywrightDispatcher, RootDispatcher, createPlaywright } from './server';

import type { Playwright as PlaywrightAPI } from './client/playwright';
import type { Platform } from './common/platform';
import type { Language } from './utils';
import type { Platform } from './utils/platform';

export function createInProcessPlaywright(platform: Platform): PlaywrightAPI {
const playwright = createPlaywright({ sdkLanguage: (process.env.PW_LANG_NAME as Language | undefined) || 'javascript' });
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/inprocess.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@
* limitations under the License.
*/

import { nodePlatform } from './common/platform';
import { createInProcessPlaywright } from './inProcessFactory';
import { nodePlatform } from './utils/platform';

module.exports = createInProcessPlaywright(nodePlatform);
2 changes: 1 addition & 1 deletion packages/playwright-core/src/outofprocess.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,9 +18,9 @@ import * as childProcess from 'child_process';
import * as path from 'path';

import { Connection } from './client/connection';
import { nodePlatform } from './common/platform';
import { PipeTransport } from './protocol/transport';
import { ManualPromise } from './utils/manualPromise';
import { nodePlatform } from './utils/platform';

import type { Playwright } from './client/playwright';

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); chore: short-cut localUtils usage in JS client by pavelfeldman · Pull Request #34690 · microsoft/playwright · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/playwright-core/src/DEPS.list
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@
**

[inprocess.ts]
common/
utils/

[outofprocess.ts]
client/
Expand Down
4 changes: 2 additions & 2 deletions packages/playwright-core/src/client/android.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,7 +31,7 @@ import type { Page } from './page';
import type * as types from './types';
import type * as api from '../../types/types';
import type { AndroidServerLauncherImpl } from '../androidServerImpl';
import type { Platform } from '../common/platform';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

type Direction = 'down' | 'up' | 'left' | 'right';
Expand DownExpand Up@@ -72,7 +72,7 @@ export class Android extends ChannelOwner<channels.AndroidChannel> implements ap
const headers = { 'x-playwright-browser': 'android', ...options.headers };
const localUtils = this._connection.localUtils();
const connectParams: channels.LocalUtilsConnectParams = { wsEndpoint, headers, slowMo: options.slowMo, timeout: options.timeout };
const { pipe } = await localUtils._channel.connect(connectParams);
const { pipe } = await localUtils.connect(connectParams);
const closePipe = () => pipe.close().catch(() => {});
const connection = new Connection(localUtils, this._platform, this._instrumentation);
connection.markAsRemote();
Expand Down
4 changes: 2 additions & 2 deletions packages/playwright-core/src/client/browserContext.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,8 +45,8 @@ import type { BrowserType } from './browserType';
import type { BrowserContextOptions, Headers, LaunchOptions, StorageState, WaitForEventOptions } from './types';
import type * as structs from '../../types/structs';
import type * as api from '../../types/types';
import type { Platform } from '../common/platform';
import type { URLMatch } from '../utils/isomorphic/urlMatch';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel> implements api.BrowserContext {
Expand DownExpand Up@@ -485,7 +485,7 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel>
const needCompressed = harParams.path.endsWith('.zip');
if (isCompressed && !needCompressed) {
await artifact.saveAs(harParams.path + '.tmp');
await this._connection.localUtils()._channel.harUnzip({ zipFile: harParams.path + '.tmp', harFile: harParams.path });
await this._connection.localUtils().harUnzip({ zipFile: harParams.path + '.tmp', harFile: harParams.path });
} else {
await artifact.saveAs(harParams.path);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/browserType.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -133,7 +133,7 @@ export class BrowserType extends ChannelOwner<channels.BrowserTypeChannel> imple
};
if ((params as any).__testHookRedirectPortForwarding)
connectParams.socksProxyRedirectPortForTest = (params as any).__testHookRedirectPortForwarding;
const { pipe, headers: connectHeaders } = await localUtils._channel.connect(connectParams);
const { pipe, headers: connectHeaders } = await localUtils.connect(connectParams);
const closePipe = () => pipe.close().catch(() => {});
const connection = new Connection(localUtils, this._platform, this._instrumentation);
connection.markAsRemote();
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/channelOwner.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,8 +24,8 @@ import { zones } from '../utils/zones';
import type { ClientInstrumentation } from './clientInstrumentation';
import type { Connection } from './connection';
import type { Logger } from './types';
import type { Platform } from '../common/platform';
import type { ValidatorContext } from '../protocol/validator';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

type Listener = (...args: any[]) => void;
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/clientHelper.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,7 +18,7 @@
import { isString } from '../utils/rtti';

import type * as types from './types';
import type { Platform } from '../common/platform';
import type { Platform } from '../utils/platform';

export function envObjectToArray(env: types.Env): { name: string, value: string }[] {
const result: { name: string, value: string }[] = [];
Expand Down
4 changes: 2 additions & 2 deletions packages/playwright-core/src/client/connection.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -47,8 +47,8 @@ import { formatCallLog, rewriteErrorMessage } from '../utils/stackTrace';
import { zones } from '../utils/zones';

import type { ClientInstrumentation } from './clientInstrumentation';
import type { Platform } from '../common/platform';
import type { ValidatorContext } from '../protocol/validator';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

class Root extends ChannelOwner<channels.RootChannel> {
Expand DownExpand Up@@ -142,7 +142,7 @@ export class Connection extends EventEmitter {
const location = frames[0] ? { file: frames[0].file, line: frames[0].line, column: frames[0].column } : undefined;
const metadata: channels.Metadata = { apiName, location, internal: !apiName, stepId };
if (this._tracingCount && frames && type !== 'LocalUtils')
this._localUtils?._channel.addStackToTracingNoReply({ callData: { stack: frames, id } }).catch(() => {});
this._localUtils?.addStackToTracingNoReply({ callData: { stack: frames, id } }).catch(() => {});
// We need to exit zones before calling into the server, otherwise
// when we receive events from the server, we would be in an API zone.
zones.empty().run(() => this.onmessage({ ...message, metadata }));
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/consoleMessage.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,7 +18,7 @@ import { JSHandle } from './jsHandle';
import { Page } from './page';

import type * as api from '../../types/types';
import type { Platform } from '../common/platform';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

type ConsoleMessageLocation = channels.BrowserContextConsoleEvent['location'];
Expand Down
9 changes: 5 additions & 4 deletions packages/playwright-core/src/client/elementHandle.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,7 +31,7 @@ import type { Locator } from './locator';
import type { FilePayload, Rect, SelectOption, SelectOptionOptions } from './types';
import type * as structs from '../../types/structs';
import type * as api from '../../types/types';
import type { Platform } from '../common/platform';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';

const pipelineAsync = promisify(pipeline);
Expand DownExpand Up@@ -192,12 +192,13 @@ export class ElementHandle<T extends Node = Node> extends JSHandle<T> implements
return value === undefined ? null : value;
}

async screenshot(options: Omit<channels.ElementHandleScreenshotOptions, 'mask'> & { path?: string, mask?: Locator[] } = {}): Promise<Buffer> {
async screenshot(options: Omit<channels.ElementHandleScreenshotOptions, 'mask'> & { path?: string, mask?: api.Locator[] } = {}): Promise<Buffer> {
const mask = options.mask as Locator[] | undefined;
const copy: channels.ElementHandleScreenshotOptions = { ...options, mask: undefined };
if (!copy.type)
copy.type = determineScreenshotType(options);
if (options.mask) {
copy.mask = options.mask.map(locator => ({
if (mask) {
copy.mask = mask.map(locator => ({
frame: locator._frame._channel,
selector: locator._selector,
}));
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/fetch.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -28,8 +28,8 @@ import type { Playwright } from './playwright';
import type { ClientCertificate, FilePayload, Headers, SetStorageState, StorageState } from './types';
import type { Serializable } from '../../types/structs';
import type * as api from '../../types/types';
import type { Platform } from '../common/platform';
import type { HeadersArray, NameValue } from '../common/types';
import type { Platform } from '../utils/platform';
import type * as channels from '@protocol/channels';
import type * as fs from 'fs';

Expand Down
6 changes: 3 additions & 3 deletions packages/playwright-core/src/client/harRouter.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,7 +31,7 @@ export class HarRouter {
private _options: { urlMatch?: URLMatch; baseURL?: string; };

static async create(localUtils: LocalUtils, file: string, notFoundAction: HarNotFoundAction, options: { urlMatch?: URLMatch }): Promise<HarRouter> {
const { harId, error } = await localUtils._channel.harOpen({ file });
const { harId, error } = await localUtils.harOpen({ file });
if (error)
throw new Error(error);
return new HarRouter(localUtils, harId!, notFoundAction, options);
Expand All@@ -47,7 +47,7 @@ export class HarRouter {
private async _handle(route: Route) {
const request = route.request();

const response = await this._localUtils._channel.harLookup({
const response = await this._localUtils.harLookup({
harId: this._harId,
url: request.url(),
method: request.method(),
Expand DownExpand Up@@ -103,6 +103,6 @@ export class HarRouter {
}

dispose() {
this._localUtils._channel.harClose({ harId: this._harId }).catch(() => {});
this._localUtils.harClose({ harId: this._harId }).catch(() => {});
}
}
40 changes: 40 additions & 0 deletions packages/playwright-core/src/client/localUtils.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,8 +15,10 @@
*/

import { ChannelOwner } from './channelOwner';
import * as localUtils from '../utils/localUtils';

import type { Size } from './types';
import type { HarBackend } from '../utils/harBackend';
import type * as channels from '@protocol/channels';

type DeviceDescriptor = {
Expand All@@ -31,6 +33,8 @@ type Devices = { [name: string]: DeviceDescriptor };

export class LocalUtils extends ChannelOwner<channels.LocalUtilsChannel> {
readonly devices: Devices;
private _harBackends = new Map<string, HarBackend>();
private _stackSessions = new Map<string, localUtils.StackSession>();

constructor(parent: ChannelOwner, type: string, guid: string, initializer: channels.LocalUtilsInitializer) {
super(parent, type, guid, initializer);
Expand All@@ -39,4 +43,40 @@ export class LocalUtils extends ChannelOwner<channels.LocalUtilsChannel> {
for (const { name, descriptor } of initializer.deviceDescriptors)
this.devices[name] = descriptor;
}

async zip(params: channels.LocalUtilsZipParams): Promise<void> {
return await localUtils.zip(this._platform, this._stackSessions, params);
}

async harOpen(params: channels.LocalUtilsHarOpenParams): Promise<channels.LocalUtilsHarOpenResult> {
return await localUtils.harOpen(this._harBackends, params);
}

async harLookup(params: channels.LocalUtilsHarLookupParams): Promise<channels.LocalUtilsHarLookupResult> {
return await localUtils.harLookup(this._harBackends, params);
}

async harClose(params: channels.LocalUtilsHarCloseParams): Promise<void> {
return await localUtils.harClose(this._harBackends, params);
}

async harUnzip(params: channels.LocalUtilsHarUnzipParams): Promise<void> {
return await localUtils.harUnzip(params);
}

async tracingStarted(params: channels.LocalUtilsTracingStartedParams): Promise<channels.LocalUtilsTracingStartedResult> {
return await localUtils.tracingStarted(this._stackSessions, params);
}

async traceDiscarded(params: channels.LocalUtilsTraceDiscardedParams): Promise<void> {
return await localUtils.traceDiscarded(this._platform, this._stackSessions, params);
}

async addStackToTracingNoReply(params: channels.LocalUtilsAddStackToTracingNoReplyParams): Promise<void> {
return await localUtils.addStackToTracingNoReply(this._stackSessions, params);
}

async connect(params: channels.LocalUtilsConnectParams): Promise<channels.LocalUtilsConnectResult> {
return await this._channel.connect(params);
}
}
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/selectors.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@
import { ChannelOwner } from './channelOwner';
import { evaluationScript } from './clientHelper';
import { setTestIdAttribute, testIdAttributeName } from './locator';
import { nodePlatform } from '../common/platform';
import { nodePlatform } from '../utils/platform';

import type { SelectorEngine } from './types';
import type * as api from '../../types/types';
Expand Down
10 changes: 5 additions & 5 deletions packages/playwright-core/src/client/tracing.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -69,7 +69,7 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
this._isTracing = true;
this._connection.setIsTracing(true);
}
const result = await this._connection.localUtils()._channel.tracingStarted({ tracesDir: this._tracesDir, traceName });
const result = await this._connection.localUtils().tracingStarted({ tracesDir: this._tracesDir, traceName });
this._stacksId = result.stacksId;
}

Expand All@@ -89,15 +89,15 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
// Not interested in artifacts.
await this._channel.tracingStopChunk({ mode: 'discard' });
if (this._stacksId)
await this._connection.localUtils()._channel.traceDiscarded({ stacksId: this._stacksId });
await this._connection.localUtils().traceDiscarded({ stacksId: this._stacksId });
return;
}

const isLocal = !this._connection.isRemote();

if (isLocal) {
const result = await this._channel.tracingStopChunk({ mode: 'entries' });
await this._connection.localUtils()._channel.zip({ zipFile: filePath, entries: result.entries!, mode: 'write', stacksId: this._stacksId, includeSources: this._includeSources });
await this._connection.localUtils().zip({ zipFile: filePath, entries: result.entries!, mode: 'write', stacksId: this._stacksId, includeSources: this._includeSources });
return;
}

Expand All@@ -106,7 +106,7 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
// The artifact may be missing if the browser closed while stopping tracing.
if (!result.artifact) {
if (this._stacksId)
await this._connection.localUtils()._channel.traceDiscarded({ stacksId: this._stacksId });
await this._connection.localUtils().traceDiscarded({ stacksId: this._stacksId });
return;
}

Expand All@@ -115,7 +115,7 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
await artifact.saveAs(filePath);
await artifact.delete();

await this._connection.localUtils()._channel.zip({ zipFile: filePath, entries: [], mode: 'append', stacksId: this._stacksId, includeSources: this._includeSources });
await this._connection.localUtils().zip({ zipFile: filePath, entries: [], mode: 'append', stacksId: this._stacksId, includeSources: this._includeSources });
}

_resetStackCounter() {
Expand Down
3 changes: 2 additions & 1 deletion packages/playwright-core/src/common/DEPS.list
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
[*]
../utils/
../utilsBundle.ts
../utilsBundle.ts
../zipBundle.ts
23 changes: 23 additions & 0 deletions packages/playwright-core/src/common/progress.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
/**
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

export interface Progress {
log(message: string): void;
timeUntilDeadline(): number;
isRunning(): boolean;
cleanupWhenAborted(cleanup: () => any): void;
throwIfAborted(): void;
}
2 changes: 1 addition & 1 deletion packages/playwright-core/src/inProcessFactory.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -20,8 +20,8 @@ import { Connection } from './client/connection';
import { DispatcherConnection, PlaywrightDispatcher, RootDispatcher, createPlaywright } from './server';

import type { Playwright as PlaywrightAPI } from './client/playwright';
import type { Platform } from './common/platform';
import type { Language } from './utils';
import type { Platform } from './utils/platform';

export function createInProcessPlaywright(platform: Platform): PlaywrightAPI {
const playwright = createPlaywright({ sdkLanguage: (process.env.PW_LANG_NAME as Language | undefined) || 'javascript' });
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/inprocess.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@
* limitations under the License.
*/

import { nodePlatform } from './common/platform';
import { createInProcessPlaywright } from './inProcessFactory';
import { nodePlatform } from './utils/platform';

module.exports = createInProcessPlaywright(nodePlatform);
2 changes: 1 addition & 1 deletion packages/playwright-core/src/outofprocess.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,9 +18,9 @@ import * as childProcess from 'child_process';
import * as path from 'path';

import { Connection } from './client/connection';
import { nodePlatform } from './common/platform';
import { PipeTransport } from './protocol/transport';
import { ManualPromise } from './utils/manualPromise';
import { nodePlatform } from './utils/platform';

import type { Playwright } from './client/playwright';

Expand Down
Loading