mirror of
https://github.com/microsoft/playwright.git
synced 2024-08-16 23:50:33 +03:00
chore: enable object-curly-spacing in ESLint (#9168)
This commit is contained in:
parent
03376ed44b
commit
cd22072685
@ -24,6 +24,7 @@ module.exports = {
|
||||
* Enforced rules
|
||||
*/
|
||||
// syntax preferences
|
||||
"object-curly-spacing": ["error", "always"],
|
||||
"quotes": [2, "single", {
|
||||
"avoidEscape": true,
|
||||
"allowTemplateLiterals": true
|
||||
|
@ -67,9 +67,9 @@ const test = base.extend<TestFixtures>({
|
||||
},
|
||||
});
|
||||
|
||||
for (const packageManager of ['npm', 'yarn'] as ('npm'|'yarn')[]) {
|
||||
for (const packageManager of ['npm', 'yarn'] as ('npm' | 'yarn')[]) {
|
||||
test.describe(`Package manager: ${packageManager}`, () => {
|
||||
test.use({packageManager});
|
||||
test.use({ packageManager });
|
||||
|
||||
test('should generate a project in the current directory', async ({ run }) => {
|
||||
const { exitCode, dir, stdout } = await run([], { installGitHubActions: true, testDir: 'e2e', language: 'TypeScript' });
|
||||
|
@ -167,7 +167,7 @@ const browsers = [
|
||||
{ alias: 'wk', name: 'WebKit', type: 'webkit' },
|
||||
];
|
||||
|
||||
for (const {alias, name, type} of browsers) {
|
||||
for (const { alias, name, type } of browsers) {
|
||||
commandWithOpenOptions(`${alias} [url]`, `open page in ${name}`, [])
|
||||
.action(function(url, command) {
|
||||
open({ ...command, browser: type }, url, command.target).catch(logErrorAndExit);
|
||||
|
@ -360,7 +360,7 @@ function toSelectorChannel(selector: api.AndroidSelector): channels.AndroidSelec
|
||||
focusable,
|
||||
focused,
|
||||
hasChild: hasChild ? { selector: toSelectorChannel(hasChild.selector) } : undefined,
|
||||
hasDescendant: hasDescendant ? { selector: toSelectorChannel(hasDescendant.selector), maxDepth: hasDescendant.maxDepth} : undefined,
|
||||
hasDescendant: hasDescendant ? { selector: toSelectorChannel(hasDescendant.selector), maxDepth: hasDescendant.maxDepth } : undefined,
|
||||
longClickable,
|
||||
scrollable,
|
||||
selected,
|
||||
|
@ -71,16 +71,16 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel,
|
||||
this.tracing = new Tracing(this);
|
||||
this._request = FetchRequest.from(initializer.fetchRequest);
|
||||
|
||||
this._channel.on('bindingCall', ({binding}) => this._onBinding(BindingCall.from(binding)));
|
||||
this._channel.on('bindingCall', ({ binding }) => this._onBinding(BindingCall.from(binding)));
|
||||
this._channel.on('close', () => this._onClose());
|
||||
this._channel.on('page', ({page}) => this._onPage(Page.from(page)));
|
||||
this._channel.on('page', ({ page }) => this._onPage(Page.from(page)));
|
||||
this._channel.on('route', ({ route, request }) => this._onRoute(network.Route.from(route), network.Request.from(request)));
|
||||
this._channel.on('backgroundPage', ({ page }) => {
|
||||
const backgroundPage = Page.from(page);
|
||||
this._backgroundPages.add(backgroundPage);
|
||||
this.emit(Events.BrowserContext.BackgroundPage, backgroundPage);
|
||||
});
|
||||
this._channel.on('serviceWorker', ({worker}) => {
|
||||
this._channel.on('serviceWorker', ({ worker }) => {
|
||||
const serviceWorker = Worker.from(worker);
|
||||
serviceWorker._context = this;
|
||||
this._serviceWorkers.add(serviceWorker);
|
||||
|
@ -210,7 +210,7 @@ export class BrowserType extends ChannelOwner<channels.BrowserTypeChannel, chann
|
||||
throw new Error('Connecting over CDP is only supported in Chromium.');
|
||||
const logger = params.logger;
|
||||
return this._wrapApiCall(async (channel: channels.BrowserTypeChannel) => {
|
||||
const paramsHeaders = Object.assign({'User-Agent': getUserAgent()}, params.headers);
|
||||
const paramsHeaders = Object.assign({ 'User-Agent': getUserAgent() }, params.headers);
|
||||
const headers = paramsHeaders ? headersObjectToArray(paramsHeaders) : undefined;
|
||||
const result = await channel.connectOverCDP({
|
||||
endpointURL,
|
||||
|
@ -108,7 +108,7 @@ export class Touchscreen implements api.Touchscreen {
|
||||
|
||||
async tap(x: number, y: number) {
|
||||
await this._page._wrapApiCall(async channel => {
|
||||
await channel.touchscreenTap({x, y});
|
||||
await channel.touchscreenTap({ x, y });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ export class JSHandle<T = any> extends ChannelOwner<channels.JSHandleChannel, ch
|
||||
constructor(parent: ChannelOwner, type: string, guid: string, initializer: channels.JSHandleInitializer) {
|
||||
super(parent, type, guid, initializer);
|
||||
this._preview = this._initializer.preview;
|
||||
this._channel.on('previewUpdated', ({preview}) => this._preview = preview);
|
||||
this._channel.on('previewUpdated', ({ preview }) => this._preview = preview);
|
||||
}
|
||||
|
||||
async evaluate<R, Arg>(pageFunction: structs.PageFunctionOn<T, Arg, R>, arg?: Arg): Promise<R> {
|
||||
|
@ -491,7 +491,7 @@ export class Page extends ChannelOwner<channels.PageChannel, channels.PageInitia
|
||||
});
|
||||
}
|
||||
|
||||
async close(options: { runBeforeUnload?: boolean } = {runBeforeUnload: undefined}) {
|
||||
async close(options: { runBeforeUnload?: boolean } = { runBeforeUnload: undefined }) {
|
||||
try {
|
||||
await this._wrapApiCall(async (channel: channels.PageChannel) => {
|
||||
if (this._ownedContext)
|
||||
|
@ -65,7 +65,7 @@ export class BrowserContextDispatcher extends Dispatcher<BrowserContext, channel
|
||||
this._dispatchEvent('backgroundPage', { page: new PageDispatcher(this._scope, page) });
|
||||
context.on(CRBrowserContext.CREvents.BackgroundPage, page => this._dispatchEvent('backgroundPage', { page: new PageDispatcher(this._scope, page) }));
|
||||
for (const serviceWorker of (context as CRBrowserContext).serviceWorkers())
|
||||
this._dispatchEvent('serviceWorker', { worker: new WorkerDispatcher(this._scope, serviceWorker)});
|
||||
this._dispatchEvent('serviceWorker', { worker: new WorkerDispatcher(this._scope, serviceWorker) });
|
||||
context.on(CRBrowserContext.CREvents.ServiceWorker, serviceWorker => this._dispatchEvent('serviceWorker', { worker: new WorkerDispatcher(this._scope, serviceWorker) }));
|
||||
}
|
||||
context.on(BrowserContext.Events.Request, (request: Request) => {
|
||||
@ -84,7 +84,7 @@ export class BrowserContextDispatcher extends Dispatcher<BrowserContext, channel
|
||||
responseEndTiming: request._responseEndTiming,
|
||||
page: PageDispatcher.fromNullable(this._scope, request.frame()._page.initializedOrUndefined())
|
||||
}));
|
||||
context.on(BrowserContext.Events.RequestFinished, ({ request, response}: { request: Request, response: Response | null }) => this._dispatchEvent('requestFinished', {
|
||||
context.on(BrowserContext.Events.RequestFinished, ({ request, response }: { request: Request, response: Response | null }) => this._dispatchEvent('requestFinished', {
|
||||
request: RequestDispatcher.from(scope, request),
|
||||
response: ResponseDispatcher.fromNullable(scope, response),
|
||||
responseEndTiming: request._responseEndTiming,
|
||||
|
@ -56,7 +56,7 @@ export class BrowserTypeDispatcher extends Dispatcher<BrowserType, channels.Brow
|
||||
const waitForNextTask = params.slowMo
|
||||
? (cb: () => any) => setTimeout(cb, params.slowMo)
|
||||
: makeWaitForNextTask();
|
||||
const paramsHeaders = Object.assign({'User-Agent': getUserAgent()}, params.headers || {});
|
||||
const paramsHeaders = Object.assign({ 'User-Agent': getUserAgent() }, params.headers || {});
|
||||
const ws = new WebSocket(params.wsEndpoint, [], {
|
||||
perMessageDeflate: false,
|
||||
maxPayload: 256 * 1024 * 1024, // 256Mb,
|
||||
|
@ -40,7 +40,7 @@ export class Accessibility {
|
||||
interestingOnly = true,
|
||||
root = null,
|
||||
} = options;
|
||||
const {tree, needle} = await this._getAXTree(root || undefined);
|
||||
const { tree, needle } = await this._getAXTree(root || undefined);
|
||||
if (!interestingOnly) {
|
||||
if (root)
|
||||
return needle && serializeTree(needle)[0];
|
||||
|
@ -76,7 +76,7 @@ export abstract class BrowserContext extends SdkObject {
|
||||
this._closePromise = new Promise(fulfill => this._closePromiseFulfill = fulfill);
|
||||
|
||||
if (this._options.recordHar)
|
||||
this._harRecorder = new HarRecorder(this, {...this._options.recordHar, path: path.join(this._browser.options.artifactsDir, `${createGuid()}.har`)});
|
||||
this._harRecorder = new HarRecorder(this, { ...this._options.recordHar, path: path.join(this._browser.options.artifactsDir, `${createGuid()}.har`) });
|
||||
|
||||
this.tracing = new Tracing(this);
|
||||
this.fetchRequest = new BrowserContextFetchRequest(this);
|
||||
|
@ -54,7 +54,7 @@ export class Chromium extends BrowserType {
|
||||
controller.setLogName('browser');
|
||||
return controller.run(async progress => {
|
||||
return await this._connectOverCDPInternal(progress, endpointURL, options);
|
||||
}, TimeoutSettings.timeout({timeout}));
|
||||
}, TimeoutSettings.timeout({ timeout }));
|
||||
}
|
||||
|
||||
async _connectOverCDPInternal(progress: Progress, endpointURL: string, options: { slowMo?: number, headers?: types.HeadersArray }, onClose?: () => Promise<void>) {
|
||||
|
@ -22,7 +22,7 @@ import * as accessibility from '../accessibility';
|
||||
import * as types from '../types';
|
||||
|
||||
export async function getAccessibilityTree(client: CRSession, needle?: dom.ElementHandle): Promise<{tree: accessibility.AXNode, needle: accessibility.AXNode | null}> {
|
||||
const {nodes} = await client.send('Accessibility.getFullAXTree');
|
||||
const { nodes } = await client.send('Accessibility.getFullAXTree');
|
||||
const tree = CRAXNode.createTree(client, nodes);
|
||||
return {
|
||||
tree,
|
||||
@ -97,7 +97,7 @@ class CRAXNode implements accessibility.AXNode {
|
||||
|
||||
async _findElement(element: dom.ElementHandle): Promise<CRAXNode | null> {
|
||||
const objectId = element._objectId;
|
||||
const {node: {backendNodeId}} = await this._client.send('DOM.describeNode', { objectId });
|
||||
const { node: { backendNodeId } } = await this._client.send('DOM.describeNode', { objectId });
|
||||
const needle = this.find(node => node._payload.backendDOMNodeId === backendNodeId);
|
||||
return needle || null;
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ export class CRBrowser extends Browser {
|
||||
await Promise.all([...this._crPages.values()].map(page => page.pageOrError()));
|
||||
}
|
||||
|
||||
_onAttachedToTarget({targetInfo, sessionId, waitingForDebugger}: Protocol.Target.attachedToTargetPayload) {
|
||||
_onAttachedToTarget({ targetInfo, sessionId, waitingForDebugger }: Protocol.Target.attachedToTargetPayload) {
|
||||
if (targetInfo.type === 'browser')
|
||||
return;
|
||||
const session = this._connection.session(sessionId)!;
|
||||
|
@ -172,7 +172,7 @@ export class CRSession extends EventEmitter {
|
||||
throw new ProtocolError(true, `Target closed`);
|
||||
const id = this._connection._rawSend(this._sessionId, method, params);
|
||||
return new Promise((resolve, reject) => {
|
||||
this._callbacks.set(id, {resolve, reject, error: new ProtocolError(false), method});
|
||||
this._callbacks.set(id, { resolve, reject, error: new ProtocolError(false), method });
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@ class JSCoverage {
|
||||
this._client.send('Profiler.enable'),
|
||||
this._client.send('Profiler.startPreciseCoverage', { callCount: true, detailed: true }),
|
||||
this._client.send('Debugger.enable'),
|
||||
this._client.send('Debugger.setSkipAllPauses', {skip: true})
|
||||
this._client.send('Debugger.setSkipAllPauses', { skip: true })
|
||||
]);
|
||||
}
|
||||
|
||||
@ -106,7 +106,7 @@ class JSCoverage {
|
||||
if (!event.url && !this._reportAnonymousScripts)
|
||||
return;
|
||||
// This might fail if the page has already navigated away.
|
||||
const response = await this._client._sendMayFail('Debugger.getScriptSource', {scriptId: event.scriptId});
|
||||
const response = await this._client._sendMayFail('Debugger.getScriptSource', { scriptId: event.scriptId });
|
||||
if (response)
|
||||
this._scriptSources.set(event.scriptId, response.scriptSource);
|
||||
}
|
||||
@ -130,7 +130,7 @@ class JSCoverage {
|
||||
continue;
|
||||
const source = this._scriptSources.get(entry.scriptId);
|
||||
if (source)
|
||||
coverage.push({...entry, source});
|
||||
coverage.push({ ...entry, source });
|
||||
else
|
||||
coverage.push(entry);
|
||||
}
|
||||
@ -157,7 +157,7 @@ class CSSCoverage {
|
||||
|
||||
async start(options: types.CSSCoverageOptions = {}) {
|
||||
assert(!this._enabled, 'CSSCoverage is already enabled');
|
||||
const {resetOnNavigation = true} = options;
|
||||
const { resetOnNavigation = true } = options;
|
||||
this._resetOnNavigation = resetOnNavigation;
|
||||
this._enabled = true;
|
||||
this._stylesheetURLs.clear();
|
||||
@ -186,7 +186,7 @@ class CSSCoverage {
|
||||
if (!header.sourceURL)
|
||||
return;
|
||||
// This might fail if the page has already navigated away.
|
||||
const response = await this._client._sendMayFail('CSS.getStyleSheetText', {styleSheetId: header.styleSheetId});
|
||||
const response = await this._client._sendMayFail('CSS.getStyleSheetText', { styleSheetId: header.styleSheetId });
|
||||
if (response) {
|
||||
this._stylesheetURLs.set(header.styleSheetId, header.sourceURL);
|
||||
this._stylesheetSources.set(header.styleSheetId, response.text);
|
||||
@ -266,7 +266,7 @@ function convertToDisjointRanges(nestedRanges: {
|
||||
if (lastResult && lastResult.end === lastOffset)
|
||||
lastResult.end = point.offset;
|
||||
else
|
||||
results.push({start: lastOffset, end: point.offset});
|
||||
results.push({ start: lastOffset, end: point.offset });
|
||||
}
|
||||
lastOffset = point.offset;
|
||||
if (point.type === 0)
|
||||
|
@ -28,7 +28,7 @@ declare global {
|
||||
export class DragManager {
|
||||
private _crPage: CRPage;
|
||||
private _dragState: Protocol.Input.DragData | null = null;
|
||||
private _lastPosition = {x: 0, y: 0};
|
||||
private _lastPosition = { x: 0, y: 0 };
|
||||
constructor(page: CRPage) {
|
||||
this._crPage = page;
|
||||
}
|
||||
@ -50,7 +50,7 @@ export class DragManager {
|
||||
}
|
||||
|
||||
async interceptDragCausedByMove(x: number, y: number, button: types.MouseButton | 'none', buttons: Set<types.MouseButton>, modifiers: Set<types.KeyboardModifier>, moveCallback: () => Promise<void>): Promise<void> {
|
||||
this._lastPosition = {x, y};
|
||||
this._lastPosition = { x, y };
|
||||
if (this._dragState) {
|
||||
await this._crPage._mainFrameSession._client.send('Input.dispatchDragEvent', {
|
||||
type: 'dragOver',
|
||||
@ -75,15 +75,15 @@ export class DragManager {
|
||||
const dragListener = (event: Event) => dragEvent = event;
|
||||
const mouseListener = () => {
|
||||
didStartDrag = new Promise<boolean>(callback => {
|
||||
window.addEventListener('dragstart', dragListener, {once: true, capture: true});
|
||||
window.addEventListener('dragstart', dragListener, { once: true, capture: true });
|
||||
setTimeout(() => callback(dragEvent ? !dragEvent.defaultPrevented : false), 0);
|
||||
});
|
||||
};
|
||||
window.addEventListener('mousemove', mouseListener, {once: true, capture: true});
|
||||
window.addEventListener('mousemove', mouseListener, { once: true, capture: true });
|
||||
window.__cleanupDrag = async () => {
|
||||
const val = await didStartDrag;
|
||||
window.removeEventListener('mousemove', mouseListener, {capture: true});
|
||||
window.removeEventListener('dragstart', dragListener, {capture: true});
|
||||
window.removeEventListener('mousemove', mouseListener, { capture: true });
|
||||
window.removeEventListener('dragstart', dragListener, { capture: true });
|
||||
return val;
|
||||
};
|
||||
}).toString(), true, 'utility').catch(() => {});
|
||||
@ -91,7 +91,7 @@ export class DragManager {
|
||||
|
||||
client.on('Input.dragIntercepted', onDragIntercepted!);
|
||||
try {
|
||||
await client.send('Input.setInterceptDrags', {enabled: true});
|
||||
await client.send('Input.setInterceptDrags', { enabled: true });
|
||||
} catch {
|
||||
// If Input.setInterceptDrags is not supported, just do a regular move.
|
||||
// This can be removed once we stop supporting old Electron.
|
||||
@ -105,7 +105,7 @@ export class DragManager {
|
||||
}))).some(x => x);
|
||||
this._dragState = expectingDrag ? (await dragInterceptedPromise).data : null;
|
||||
client.off('Input.dragIntercepted', onDragIntercepted!);
|
||||
await client.send('Input.setInterceptDrags', {enabled: false});
|
||||
await client.send('Input.setInterceptDrags', { enabled: false });
|
||||
|
||||
|
||||
if (this._dragState) {
|
||||
|
@ -106,9 +106,9 @@ export class CRExecutionContext implements js.ExecutionContextDelegate {
|
||||
|
||||
function rewriteError(error: Error): Protocol.Runtime.evaluateReturnValue {
|
||||
if (error.message.includes('Object reference chain is too long'))
|
||||
return {result: {type: 'undefined'}};
|
||||
return { result: { type: 'undefined' } };
|
||||
if (error.message.includes('Object couldn\'t be returned by value'))
|
||||
return {result: {type: 'undefined'}};
|
||||
return { result: { type: 'undefined' } };
|
||||
|
||||
if (error instanceof TypeError && error.message.startsWith('Converting circular structure to JSON'))
|
||||
rewriteErrorMessage(error, error.message + ' Are you passing a nested JSHandle?');
|
||||
|
@ -105,7 +105,7 @@ export class CRNetworkManager {
|
||||
this._client.send('Network.setCacheDisabled', { cacheDisabled: true }),
|
||||
this._client.send('Fetch.enable', {
|
||||
handleAuthRequests: true,
|
||||
patterns: [{urlPattern: '*', requestStage: 'Request'}, {urlPattern: '*', requestStage: 'Response'}],
|
||||
patterns: [{ urlPattern: '*', requestStage: 'Request' }, { urlPattern: '*', requestStage: 'Response' }],
|
||||
}),
|
||||
]);
|
||||
} else {
|
||||
@ -146,7 +146,7 @@ export class CRNetworkManager {
|
||||
response = 'ProvideCredentials';
|
||||
this._attemptedAuthentications.add(event.requestId);
|
||||
}
|
||||
const {username, password} = this._credentials || {username: undefined, password: undefined};
|
||||
const { username, password } = this._credentials || { username: undefined, password: undefined };
|
||||
this._client._sendMayFail('Fetch.continueWithAuth', {
|
||||
requestId: event.requestId,
|
||||
authChallengeResponse: { response, username, password },
|
||||
|
@ -460,7 +460,7 @@ class FrameSession {
|
||||
this._addBrowserListeners();
|
||||
const promises: Promise<any>[] = [
|
||||
this._client.send('Page.enable'),
|
||||
this._client.send('Page.getFrameTree').then(({frameTree}) => {
|
||||
this._client.send('Page.getFrameTree').then(({ frameTree }) => {
|
||||
if (this._isMainFrame()) {
|
||||
this._handleFrameTree(frameTree);
|
||||
this._addRendererListeners();
|
||||
@ -815,7 +815,7 @@ class FrameSession {
|
||||
}
|
||||
|
||||
_onLogEntryAdded(event: Protocol.Log.entryAddedPayload) {
|
||||
const {level, text, args, source, url, lineNumber} = event.entry;
|
||||
const { level, text, args, source, url, lineNumber } = event.entry;
|
||||
if (args)
|
||||
args.map(arg => releaseObject(this._client, arg.objectId!));
|
||||
if (source !== 'worker') {
|
||||
@ -853,7 +853,7 @@ class FrameSession {
|
||||
}
|
||||
|
||||
_onScreencastFrame(payload: Protocol.Page.screencastFramePayload) {
|
||||
this._client.send('Page.screencastFrameAck', {sessionId: payload.sessionId}).catch(() => {});
|
||||
this._client.send('Page.screencastFrameAck', { sessionId: payload.sessionId }).catch(() => {});
|
||||
const buffer = Buffer.from(payload.data, 'base64');
|
||||
this._page.emit(Page.Events.ScreencastFrame, {
|
||||
buffer,
|
||||
|
@ -21,17 +21,17 @@ import { CRSession } from './crConnection';
|
||||
import { readProtocolStream } from './crProtocolHelper';
|
||||
|
||||
const PagePaperFormats: { [key: string]: { width: number, height: number }} = {
|
||||
letter: {width: 8.5, height: 11},
|
||||
legal: {width: 8.5, height: 14},
|
||||
tabloid: {width: 11, height: 17},
|
||||
ledger: {width: 17, height: 11},
|
||||
a0: {width: 33.1, height: 46.8 },
|
||||
a1: {width: 23.4, height: 33.1 },
|
||||
a2: {width: 16.54, height: 23.4 },
|
||||
a3: {width: 11.7, height: 16.54 },
|
||||
a4: {width: 8.27, height: 11.7 },
|
||||
a5: {width: 5.83, height: 8.27 },
|
||||
a6: {width: 4.13, height: 5.83 },
|
||||
letter: { width: 8.5, height: 11 },
|
||||
legal: { width: 8.5, height: 14 },
|
||||
tabloid: { width: 11, height: 17 },
|
||||
ledger: { width: 17, height: 11 },
|
||||
a0: { width: 33.1, height: 46.8 },
|
||||
a1: { width: 23.4, height: 33.1 },
|
||||
a2: { width: 16.54, height: 23.4 },
|
||||
a3: { width: 11.7, height: 16.54 },
|
||||
a4: { width: 8.27, height: 11.7 },
|
||||
a5: { width: 5.83, height: 8.27 },
|
||||
a6: { width: 4.13, height: 5.83 },
|
||||
};
|
||||
|
||||
const unitToPixels: { [key: string]: number } = {
|
||||
|
@ -49,7 +49,7 @@ export async function readProtocolStream(client: CRSession, handle: string, path
|
||||
}
|
||||
const bufs = [];
|
||||
while (!eof) {
|
||||
const response = await client.send('IO.read', {handle});
|
||||
const response = await client.send('IO.read', { handle });
|
||||
eof = response.eof;
|
||||
const buf = Buffer.from(response.data, response.base64Encoded ? 'base64' : undefined);
|
||||
bufs.push(buf);
|
||||
@ -58,7 +58,7 @@ export async function readProtocolStream(client: CRSession, handle: string, path
|
||||
}
|
||||
if (fd)
|
||||
await fd.close();
|
||||
await client.send('IO.close', {handle});
|
||||
await client.send('IO.close', { handle });
|
||||
return Buffer.concat(bufs);
|
||||
}
|
||||
|
||||
@ -82,7 +82,7 @@ export function exceptionToError(exceptionDetails: Protocol.Runtime.ExceptionDet
|
||||
messageWithName = lines.slice(0, firstStackTraceLine).join('\n');
|
||||
stack = messageWithStack;
|
||||
}
|
||||
const {name, message} = splitErrorMessage(messageWithName);
|
||||
const { name, message } = splitErrorMessage(messageWithName);
|
||||
|
||||
const err = new Error(message);
|
||||
err.stack = stack;
|
||||
|
@ -142,7 +142,7 @@ export function parseComponentSelector(selector: string): ParsedComponentSelecto
|
||||
// check property is truthy: [enabled]
|
||||
if (next() === ']') {
|
||||
eat1();
|
||||
return {jsonPath, op: '<truthy>', value: null, caseSensetive: false};
|
||||
return { jsonPath, op: '<truthy>', value: null, caseSensetive: false };
|
||||
}
|
||||
|
||||
const operator = readOperator();
|
||||
@ -181,7 +181,7 @@ export function parseComponentSelector(selector: string): ParsedComponentSelecto
|
||||
eat1();
|
||||
if (operator !== '=' && typeof value !== 'string')
|
||||
throw new Error(`Error while parsing selector \`${selector}\` - cannot use ${operator} in attribute with non-string matching value - ${value}`);
|
||||
return {jsonPath, op: operator, value, caseSensetive};
|
||||
return { jsonPath, op: operator, value, caseSensetive };
|
||||
}
|
||||
|
||||
const result: ParsedComponentSelector = {
|
||||
|
@ -277,7 +277,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
||||
|
||||
const [quads, metrics] = await Promise.all([
|
||||
this._page._delegate.getContentQuads(this),
|
||||
this._page.mainFrame()._utilityContext().then(utility => utility.evaluate(() => ({width: innerWidth, height: innerHeight}))),
|
||||
this._page.mainFrame()._utilityContext().then(utility => utility.evaluate(() => ({ width: innerWidth, height: innerHeight }))),
|
||||
] as const);
|
||||
if (!quads || !quads.length)
|
||||
return 'error:notvisible';
|
||||
|
@ -26,7 +26,7 @@ import { TimeoutSettings } from '../../utils/timeoutSettings';
|
||||
import { WebSocketTransport } from '../transport';
|
||||
import { launchProcess, envArrayToObject } from '../../utils/processLauncher';
|
||||
import { BrowserContext } from '../browserContext';
|
||||
import type {BrowserWindow} from 'electron';
|
||||
import type { BrowserWindow } from 'electron';
|
||||
import { Progress, ProgressController } from '../progress';
|
||||
import { helper } from '../helper';
|
||||
import { eventsHelper } from '../../utils/eventsHelper';
|
||||
|
@ -91,7 +91,7 @@ export abstract class FetchRequest extends SdkObject {
|
||||
headers['accept-encoding'] = 'gzip,deflate,br';
|
||||
|
||||
if (defaults.extraHTTPHeaders) {
|
||||
for (const {name, value} of defaults.extraHTTPHeaders)
|
||||
for (const { name, value } of defaults.extraHTTPHeaders)
|
||||
headers[name.toLowerCase()] = value;
|
||||
}
|
||||
|
||||
@ -235,7 +235,7 @@ export abstract class FetchRequest extends SdkObject {
|
||||
const auth = response.headers['www-authenticate'];
|
||||
const credentials = this._defaultOptions().httpCredentials;
|
||||
if (auth?.trim().startsWith('Basic ') && credentials) {
|
||||
const {username, password} = credentials;
|
||||
const { username, password } = credentials;
|
||||
const encoded = Buffer.from(`${username || ''}:${password || ''}`).toString('base64');
|
||||
options.headers!['authorization'] = `Basic ${encoded}`;
|
||||
fulfill(this._sendRequest(url, options, postData));
|
||||
|
@ -106,7 +106,7 @@ export class FFBrowser extends Browser {
|
||||
}
|
||||
|
||||
_onAttachedToTarget(payload: Protocol.Browser.attachedToTargetPayload) {
|
||||
const {targetId, browserContextId, openerId, type} = payload.targetInfo;
|
||||
const { targetId, browserContextId, openerId, type } = payload.targetInfo;
|
||||
assert(type === 'page');
|
||||
const context = browserContextId ? this._contexts.get(browserContextId)! : this._defaultContext as FFBrowserContext;
|
||||
assert(context, `Unknown context id:${browserContextId}, _defaultContext: ${this._defaultContext}`);
|
||||
@ -290,7 +290,7 @@ export class FFBrowserContext extends BrowserContext {
|
||||
throw new Error('Unknown permission: ' + permission);
|
||||
return protocolPermission;
|
||||
});
|
||||
await this._browser._connection.send('Browser.grantPermissions', { origin: origin, browserContextId: this._browserContextId, permissions: filtered});
|
||||
await this._browser._connection.send('Browser.grantPermissions', { origin: origin, browserContextId: this._browserContextId, permissions: filtered });
|
||||
}
|
||||
|
||||
async _doClearPermissions() {
|
||||
|
@ -75,9 +75,9 @@ export class FFConnection extends EventEmitter {
|
||||
): Promise<Protocol.CommandReturnValues[T]> {
|
||||
this._checkClosed(method);
|
||||
const id = this.nextMessageId();
|
||||
this._rawSend({id, method, params});
|
||||
this._rawSend({ id, method, params });
|
||||
return new Promise((resolve, reject) => {
|
||||
this._callbacks.set(id, {resolve, reject, error: new ProtocolError(false), method});
|
||||
this._callbacks.set(id, { resolve, reject, error: new ProtocolError(false), method });
|
||||
});
|
||||
}
|
||||
|
||||
@ -141,7 +141,7 @@ export class FFConnection extends EventEmitter {
|
||||
}
|
||||
|
||||
createSession(sessionId: string): FFSession {
|
||||
const session = new FFSession(this, sessionId, message => this._rawSend({...message, sessionId}));
|
||||
const session = new FFSession(this, sessionId, message => this._rawSend({ ...message, sessionId }));
|
||||
this._sessions.set(sessionId, session);
|
||||
return session;
|
||||
}
|
||||
@ -193,9 +193,9 @@ export class FFSession extends EventEmitter {
|
||||
if (this._disposed)
|
||||
throw new ProtocolError(true, 'Target closed');
|
||||
const id = this._connection.nextMessageId();
|
||||
this._rawSend({method, params, id});
|
||||
this._rawSend({ method, params, id });
|
||||
return new Promise((resolve, reject) => {
|
||||
this._callbacks.set(id, {resolve, reject, error: new ProtocolError(false), method});
|
||||
this._callbacks.set(id, { resolve, reject, error: new ProtocolError(false), method });
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -111,7 +111,7 @@ function checkException(exceptionDetails?: Protocol.Runtime.ExceptionDetails) {
|
||||
|
||||
function rewriteError(error: Error): (Protocol.Runtime.evaluateReturnValue | Protocol.Runtime.callFunctionReturnValue) {
|
||||
if (error.message.includes('cyclic object value') || error.message.includes('Object is not serializable'))
|
||||
return {result: {type: 'undefined', value: undefined}};
|
||||
return { result: { type: 'undefined', value: undefined } };
|
||||
if (error instanceof TypeError && error.message.startsWith('Converting circular structure to JSON'))
|
||||
rewriteErrorMessage(error, error.message + ' Are you passing a nested JSHandle?');
|
||||
if (!js.isJavaScriptErrorInEvaluate(error) && !isSessionClosedError(error))
|
||||
|
@ -50,7 +50,7 @@ export class FFNetworkManager {
|
||||
}
|
||||
|
||||
async setRequestInterception(enabled: boolean) {
|
||||
await this._session.send('Network.setRequestInterception', {enabled});
|
||||
await this._session.send('Network.setRequestInterception', { enabled });
|
||||
}
|
||||
|
||||
_onRequestWillBeSent(event: Protocol.Network.requestWillBeSentPayload) {
|
||||
|
@ -152,7 +152,7 @@ export class FFPage implements PageDelegate {
|
||||
}
|
||||
|
||||
_onExecutionContextCreated(payload: Protocol.Runtime.executionContextCreatedPayload) {
|
||||
const {executionContextId, auxData} = payload;
|
||||
const { executionContextId, auxData } = payload;
|
||||
const frame = this._page._frameManager.frame(auxData.frameId!);
|
||||
if (!frame)
|
||||
return;
|
||||
@ -169,7 +169,7 @@ export class FFPage implements PageDelegate {
|
||||
}
|
||||
|
||||
_onExecutionContextDestroyed(payload: Protocol.Runtime.executionContextDestroyedPayload) {
|
||||
const {executionContextId} = payload;
|
||||
const { executionContextId } = payload;
|
||||
const context = this._contextIdToContext.get(executionContextId);
|
||||
if (!context)
|
||||
return;
|
||||
@ -220,7 +220,7 @@ export class FFPage implements PageDelegate {
|
||||
}
|
||||
|
||||
_onEventFired(payload: Protocol.Page.eventFiredPayload) {
|
||||
const {frameId, name} = payload;
|
||||
const { frameId, name } = payload;
|
||||
if (name === 'load')
|
||||
this._page._frameManager.frameLifecycleEvent(frameId, 'load');
|
||||
if (name === 'DOMContentLoaded')
|
||||
@ -236,7 +236,7 @@ export class FFPage implements PageDelegate {
|
||||
}
|
||||
|
||||
_onConsole(payload: Protocol.Runtime.consolePayload) {
|
||||
const {type, args, executionContextId, location} = payload;
|
||||
const { type, args, executionContextId, location } = payload;
|
||||
const context = this._contextIdToContext.get(executionContextId)!;
|
||||
this._page._addConsoleMessage(type, args.map(arg => context.createHandle(arg)), location);
|
||||
}
|
||||
@ -260,7 +260,7 @@ export class FFPage implements PageDelegate {
|
||||
}
|
||||
|
||||
async _onFileChooserOpened(payload: Protocol.Page.fileChooserOpenedPayload) {
|
||||
const {executionContextId, element} = payload;
|
||||
const { executionContextId, element } = payload;
|
||||
const context = this._contextIdToContext.get(executionContextId)!;
|
||||
const handle = context.createHandle(element).asElement()!;
|
||||
await this._page._onFileChooserOpened(handle);
|
||||
@ -284,7 +284,7 @@ export class FFPage implements PageDelegate {
|
||||
worker._createExecutionContext(new FFExecutionContext(workerSession, event.executionContextId));
|
||||
});
|
||||
workerSession.on('Runtime.console', event => {
|
||||
const {type, args, location} = event;
|
||||
const { type, args, location } = event;
|
||||
const context = worker._existingExecutionContext!;
|
||||
this._page._addConsoleMessage(type, args.map(arg => context.createHandle(arg)), location);
|
||||
});
|
||||
|
@ -1336,7 +1336,7 @@ export class Frame extends SdkObject {
|
||||
async extendInjectedScript(source: string, arg?: any): Promise<js.JSHandle> {
|
||||
const context = await this._context('main');
|
||||
const injectedScriptHandle = await context.injectedScript();
|
||||
return injectedScriptHandle.evaluateHandle((injectedScript, {source, arg}) => {
|
||||
return injectedScriptHandle.evaluateHandle((injectedScript, { source, arg }) => {
|
||||
return injectedScript.extend(source, arg);
|
||||
}, { source, arg });
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ function findReactRoots(): ReactVNode[] {
|
||||
|
||||
export const ReactEngine: SelectorEngine = {
|
||||
queryAll(scope: SelectorRoot, selector: string): Element[] {
|
||||
const {name, attributes} = parseComponentSelector(selector);
|
||||
const { name, attributes } = parseComponentSelector(selector);
|
||||
|
||||
const reactRoots = findReactRoots();
|
||||
const trees = reactRoots.map(reactRoot => buildComponentsTree(reactRoot));
|
||||
|
@ -210,7 +210,7 @@ function findVueRoots(): VueRoot[] {
|
||||
// Vue3 roots are marked with [data-v-app] attribute
|
||||
for (const node of document.querySelectorAll('[data-v-app]')) {
|
||||
if ((node as any)._vnode && (node as any)._vnode.component)
|
||||
roots.push({root: (node as any)._vnode.component, version: 3});
|
||||
roots.push({ root: (node as any)._vnode.component, version: 3 });
|
||||
}
|
||||
// Vue2 roots are referred to from elements.
|
||||
const walker = document.createTreeWalker(document, NodeFilter.SHOW_ELEMENT);
|
||||
@ -231,7 +231,7 @@ function findVueRoots(): VueRoot[] {
|
||||
|
||||
export const VueEngine: SelectorEngine = {
|
||||
queryAll(scope: SelectorRoot, selector: string): Element[] {
|
||||
const {name, attributes} = parseComponentSelector(selector);
|
||||
const { name, attributes } = parseComponentSelector(selector);
|
||||
const vueRoots = findVueRoots();
|
||||
const trees = vueRoots.map(vueRoot => vueRoot.version === 3 ? buildComponentsTreeVue3(vueRoot.root) : buildComponentsTreeVue2(vueRoot.root));
|
||||
const treeNodes = trees.map(tree => filterComponentsTree(tree, treeNode => {
|
||||
|
@ -132,7 +132,7 @@ export class JSHandle<T = any> extends SdkObject {
|
||||
|
||||
async getProperty(propertyName: string): Promise<JSHandle> {
|
||||
const objectHandle = await this.evaluateHandle((object: any, propertyName) => {
|
||||
const result: any = {__proto__: null};
|
||||
const result: any = { __proto__: null };
|
||||
result[propertyName] = object[propertyName];
|
||||
return result;
|
||||
}, propertyName);
|
||||
|
@ -54,7 +54,7 @@ export function rewriteCookies(cookies: types.SetNetworkCookieParam[]): types.Se
|
||||
assert(c.url || (c.domain && c.path), 'Cookie should have a url or a domain/path pair');
|
||||
assert(!(c.url && c.domain), 'Cookie should have either url or domain');
|
||||
assert(!(c.url && c.path), 'Cookie should have either url or path');
|
||||
const copy = {...c};
|
||||
const copy = { ...c };
|
||||
if (copy.url) {
|
||||
assert(copy.url !== 'about:blank', `Blank page can not have cookie "${c.name}"`);
|
||||
assert(!copy.url.startsWith('data:'), `Data URL page can not have cookie "${c.name}"`);
|
||||
|
@ -556,7 +556,7 @@ export class PageBinding {
|
||||
}
|
||||
|
||||
static async dispatch(page: Page, payload: string, context: dom.FrameExecutionContext) {
|
||||
const {name, seq, args} = JSON.parse(payload);
|
||||
const { name, seq, args } = JSON.parse(payload);
|
||||
try {
|
||||
assert(context.world);
|
||||
const binding = page.getBinding(name)!;
|
||||
@ -620,12 +620,12 @@ function addPageBinding(bindingName: string, needsHandle: boolean) {
|
||||
handles = new Map();
|
||||
me['handles'] = handles;
|
||||
}
|
||||
const promise = new Promise((resolve, reject) => callbacks.set(seq, {resolve, reject}));
|
||||
const promise = new Promise((resolve, reject) => callbacks.set(seq, { resolve, reject }));
|
||||
if (needsHandle) {
|
||||
handles.set(seq, args[0]);
|
||||
binding(JSON.stringify({name: bindingName, seq}));
|
||||
binding(JSON.stringify({ name: bindingName, seq }));
|
||||
} else {
|
||||
binding(JSON.stringify({name: bindingName, seq, args}));
|
||||
binding(JSON.stringify({ name: bindingName, seq, args }));
|
||||
}
|
||||
return promise;
|
||||
};
|
||||
|
@ -140,7 +140,7 @@ export class Screenshotter {
|
||||
progress.throwIfAborted(); // Screenshotting is expensive - avoid extra work.
|
||||
const shouldSetDefaultBackground = options.omitBackground && format === 'png';
|
||||
if (shouldSetDefaultBackground) {
|
||||
await this._page._delegate.setBackgroundColor({ r: 0, g: 0, b: 0, a: 0});
|
||||
await this._page._delegate.setBackgroundColor({ r: 0, g: 0, b: 0, a: 0 });
|
||||
progress.cleanupWhenAborted(() => this._page._delegate.setBackgroundColor());
|
||||
}
|
||||
progress.throwIfAborted(); // Avoid extra work.
|
||||
|
@ -42,7 +42,7 @@ export class WebKit extends BrowserType {
|
||||
}
|
||||
|
||||
_attemptToGracefullyCloseBrowser(transport: ConnectionTransport): void {
|
||||
transport.send({method: 'Playwright.close', params: {}, id: kBrowserCloseMessageId});
|
||||
transport.send({ method: 'Playwright.close', params: {}, id: kBrowserCloseMessageId });
|
||||
}
|
||||
|
||||
_defaultArgs(options: types.LaunchOptions, isPersistent: boolean, userDataDir: string): string[] {
|
||||
|
@ -21,7 +21,7 @@ import * as types from '../types';
|
||||
|
||||
export async function getAccessibilityTree(session: WKSession, needle?: dom.ElementHandle) {
|
||||
const objectId = needle ? needle._objectId : undefined;
|
||||
const {axNode} = await session.send('Page.accessibilitySnapshot', { objectId });
|
||||
const { axNode } = await session.send('Page.accessibilitySnapshot', { objectId });
|
||||
const tree = new WKAXNode(axNode);
|
||||
return {
|
||||
tree,
|
||||
@ -127,7 +127,7 @@ class WKAXNode implements accessibility.AXNode {
|
||||
}
|
||||
|
||||
isInteresting(insideControl: boolean): boolean {
|
||||
const {role, focusable} = this._payload;
|
||||
const { role, focusable } = this._payload;
|
||||
const name = this._name();
|
||||
if (role === 'ScrollArea')
|
||||
return false;
|
||||
|
@ -138,7 +138,7 @@ export class WKSession extends EventEmitter {
|
||||
const messageObj = { id, method, params };
|
||||
this._rawSend(messageObj);
|
||||
return new Promise<Protocol.CommandReturnValues[T]>((resolve, reject) => {
|
||||
this._callbacks.set(id, {resolve, reject, error: new ProtocolError(false), method});
|
||||
this._callbacks.set(id, { resolve, reject, error: new ProtocolError(false), method });
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -308,7 +308,7 @@ export class WKPage implements PageDelegate {
|
||||
this._setSession(session);
|
||||
await Promise.all([
|
||||
this._initializePageProxySession(),
|
||||
this._initializeSession(session, false, ({frameTree}) => this._handleFrameTree(frameTree)),
|
||||
this._initializeSession(session, false, ({ frameTree }) => this._handleFrameTree(frameTree)),
|
||||
]);
|
||||
pageOrError = this._page;
|
||||
} catch (e) {
|
||||
@ -552,7 +552,7 @@ export class WKPage implements PageDelegate {
|
||||
columnNumber: (columnNumber || 1) - 1,
|
||||
}
|
||||
};
|
||||
this._onConsoleRepeatCountUpdated({ count: 1});
|
||||
this._onConsoleRepeatCountUpdated({ count: 1 });
|
||||
}
|
||||
|
||||
_onConsoleRepeatCountUpdated(event: Protocol.Console.messageRepeatCountUpdatedPayload) {
|
||||
@ -983,7 +983,7 @@ export class WKPage implements PageDelegate {
|
||||
_onRequestIntercepted(session: WKSession, event: Protocol.Network.requestInterceptedPayload) {
|
||||
const request = this._requestIdToRequest.get(event.requestId);
|
||||
if (!request) {
|
||||
session.sendMayFail('Network.interceptRequestWithError', {errorType: 'Cancellation', requestId: event.requestId});
|
||||
session.sendMayFail('Network.interceptRequestWithError', { errorType: 'Cancellation', requestId: event.requestId });
|
||||
return;
|
||||
}
|
||||
if (!request._route) {
|
||||
|
@ -50,7 +50,7 @@ export class WKProvisionalPage {
|
||||
eventsHelper.addEventListener(session, 'Network.loadingFailed', overrideFrameId(e => wkPage._onLoadingFailed(e))),
|
||||
];
|
||||
|
||||
this.initializationPromise = this._wkPage._initializeSession(session, true, ({frameTree}) => this._handleFrameTree(frameTree));
|
||||
this.initializationPromise = this._wkPage._initializeSession(session, true, ({ frameTree }) => this._handleFrameTree(frameTree));
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
@ -364,7 +364,7 @@ export class Dispatcher {
|
||||
pair.result.stderr.push(chunk);
|
||||
this._reporter.onStdErr?.(chunk, pair?.test, pair?.result);
|
||||
});
|
||||
worker.on('teardownError', ({error}) => {
|
||||
worker.on('teardownError', ({ error }) => {
|
||||
this._hasWorkerErrors = true;
|
||||
this._reporter.onError?.(error);
|
||||
});
|
||||
|
@ -285,7 +285,7 @@ function positionInFile(stackLines: string[], file: string): { column: number; l
|
||||
if (!parsed || !parsed.file)
|
||||
continue;
|
||||
if (path.resolve(process.cwd(), parsed.file) === file)
|
||||
return {column: parsed.column || 0, line: parsed.line || 0};
|
||||
return { column: parsed.column || 0, line: parsed.line || 0 };
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,7 +131,7 @@ class JUnitReporter implements Reporter {
|
||||
entries.push(entry);
|
||||
|
||||
if (test.outcome() === 'skipped') {
|
||||
entry.children.push({ name: 'skipped'});
|
||||
entry.children.push({ name: 'skipped' });
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -338,7 +338,7 @@ function filterOnly(suite: Suite) {
|
||||
}
|
||||
|
||||
function filterByFocusedLine(suite: Suite, focusedTestFileLines: FilePatternFilter[]) {
|
||||
const testFileLineMatches = (testFileName: string, testLine: number) => focusedTestFileLines.some(({re, line}) => {
|
||||
const testFileLineMatches = (testFileName: string, testLine: number) => focusedTestFileLines.some(({ re, line }) => {
|
||||
re.lastIndex = 0;
|
||||
return re.test(testFileName) && (line === testLine || line === null);
|
||||
});
|
||||
|
@ -92,7 +92,7 @@ export function installTransform(): () => void {
|
||||
sourceMaps: 'both',
|
||||
} as babel.TransformOptions)!;
|
||||
if (result.code) {
|
||||
fs.mkdirSync(path.dirname(cachePath), {recursive: true});
|
||||
fs.mkdirSync(path.dirname(cachePath), { recursive: true });
|
||||
if (result.map)
|
||||
fs.writeFileSync(sourceMapPath, JSON.stringify(result.map), 'utf8');
|
||||
fs.writeFileSync(codePath, result.code, 'utf8');
|
||||
|
@ -55,7 +55,7 @@ export async function downloadBrowserWithProgressBar(title: string, browserDirec
|
||||
try {
|
||||
for (let attempt = 1, N = 3; attempt <= N; ++attempt) {
|
||||
debugLogger.log('install', `downloading ${progressBarName} - attempt #${attempt}`);
|
||||
const {error} = await downloadFile(url, zipPath, {progressCallback: progress, log: debugLogger.log.bind(debugLogger, 'install')});
|
||||
const { error } = await downloadFile(url, zipPath, { progressCallback: progress, log: debugLogger.log.bind(debugLogger, 'install') });
|
||||
if (!error) {
|
||||
debugLogger.log('install', `SUCCESS downloading ${progressBarName}`);
|
||||
break;
|
||||
@ -74,7 +74,7 @@ export async function downloadBrowserWithProgressBar(title: string, browserDirec
|
||||
debugLogger.log('install', `extracting archive`);
|
||||
debugLogger.log('install', `-- zip: ${zipPath}`);
|
||||
debugLogger.log('install', `-- location: ${browserDirectory}`);
|
||||
await extract(zipPath, { dir: browserDirectory});
|
||||
await extract(zipPath, { dir: browserDirectory });
|
||||
debugLogger.log('install', `fixing permissions at ${executablePath}`);
|
||||
await fs.promises.chmod(executablePath, 0o755);
|
||||
} catch (e) {
|
||||
|
@ -39,7 +39,7 @@ export type DependencyGroup = 'chromium' | 'firefox' | 'webkit' | 'tools';
|
||||
|
||||
export async function installDependenciesWindows(targets: Set<DependencyGroup>) {
|
||||
if (targets.has('chromium')) {
|
||||
const {code} = await utils.spawnAsync('powershell.exe', [path.join(BIN_DIRECTORY, 'install_media_pack.ps1')], { cwd: BIN_DIRECTORY, stdio: 'inherit' });
|
||||
const { code } = await utils.spawnAsync('powershell.exe', [path.join(BIN_DIRECTORY, 'install_media_pack.ps1')], { cwd: BIN_DIRECTORY, stdio: 'inherit' });
|
||||
if (code !== 0)
|
||||
throw new Error('Failed to install windows dependencies!');
|
||||
}
|
||||
@ -255,7 +255,7 @@ async function executablesOrSharedLibraries(directoryPath: string): Promise<stri
|
||||
async function missingFileDependenciesWindows(filePath: string): Promise<Array<string>> {
|
||||
const executable = path.join(__dirname, '..', '..', 'bin', 'PrintDeps.exe');
|
||||
const dirname = path.dirname(filePath);
|
||||
const {stdout, code} = await utils.spawnAsync(executable, [filePath], {
|
||||
const { stdout, code } = await utils.spawnAsync(executable, [filePath], {
|
||||
cwd: dirname,
|
||||
env: {
|
||||
...process.env,
|
||||
@ -273,7 +273,7 @@ async function missingFileDependencies(filePath: string, extraLDPaths: string[])
|
||||
let LD_LIBRARY_PATH = extraLDPaths.join(':');
|
||||
if (process.env.LD_LIBRARY_PATH)
|
||||
LD_LIBRARY_PATH = `${process.env.LD_LIBRARY_PATH}:${LD_LIBRARY_PATH}`;
|
||||
const {stdout, code} = await utils.spawnAsync('ldd', [filePath], {
|
||||
const { stdout, code } = await utils.spawnAsync('ldd', [filePath], {
|
||||
cwd: dirname,
|
||||
env: {
|
||||
...process.env,
|
||||
@ -292,7 +292,7 @@ async function missingDLOPENLibraries(libraries: string[]): Promise<string[]> {
|
||||
// NOTE: Using full-qualified path to `ldconfig` since `/sbin` is not part of the
|
||||
// default PATH in CRON.
|
||||
// @see https://github.com/microsoft/playwright/issues/3397
|
||||
const {stdout, code, error} = await utils.spawnAsync('/sbin/ldconfig', ['-p'], {});
|
||||
const { stdout, code, error } = await utils.spawnAsync('/sbin/ldconfig', ['-p'], {});
|
||||
if (code !== 0 || error)
|
||||
return [];
|
||||
const isLibraryAvailable = (library: string) => stdout.toLowerCase().includes(library.toLowerCase());
|
||||
|
@ -615,8 +615,8 @@ export class Registry {
|
||||
}[channel];
|
||||
const product = products.find((product: any) => product.Product === productName);
|
||||
const searchConfig = ({
|
||||
darwin: {platform: 'MacOS', arch: 'universal', artifact: 'pkg'},
|
||||
win32: {platform: 'Windows', arch: os.arch() === 'x64' ? 'x64' : 'x86', artifact: 'msi'},
|
||||
darwin: { platform: 'MacOS', arch: 'universal', artifact: 'pkg' },
|
||||
win32: { platform: 'Windows', arch: os.arch() === 'x64' ? 'x64' : 'x86', artifact: 'msi' },
|
||||
} as any)[process.platform];
|
||||
const release = searchConfig ? product.Releases.find((release: any) => release.Platform === searchConfig.platform && release.Architecture === searchConfig.arch) : null;
|
||||
const artifact = release ? release.Artifacts.find((artifact: any) => artifact.ArtifactName === searchConfig.artifact) : null;
|
||||
|
@ -123,7 +123,7 @@ export function downloadFile(url: string, destinationPath: string, options: {pro
|
||||
log(`running download:`);
|
||||
log(`-- from url: ${url}`);
|
||||
log(`-- to location: ${destinationPath}`);
|
||||
let fulfill: ({error}: {error: any}) => void = ({error}) => {};
|
||||
let fulfill: ({ error }: {error: any}) => void = ({ error }) => {};
|
||||
let downloadedBytes = 0;
|
||||
let totalBytes = 0;
|
||||
|
||||
@ -135,18 +135,18 @@ export function downloadFile(url: string, destinationPath: string, options: {pro
|
||||
const error = new Error(`Download failed: server returned code ${response.statusCode}. URL: ${url}`);
|
||||
// consume response data to free up memory
|
||||
response.resume();
|
||||
fulfill({error});
|
||||
fulfill({ error });
|
||||
return;
|
||||
}
|
||||
const file = fs.createWriteStream(destinationPath);
|
||||
file.on('finish', () => fulfill({error: null}));
|
||||
file.on('error', error => fulfill({error}));
|
||||
file.on('finish', () => fulfill({ error: null }));
|
||||
file.on('error', error => fulfill({ error }));
|
||||
response.pipe(file);
|
||||
totalBytes = parseInt(response.headers['content-length'] || '0', 10);
|
||||
log(`-- total bytes: ${totalBytes}`);
|
||||
if (progressCallback)
|
||||
response.on('data', onData);
|
||||
}, (error: any) => fulfill({error}));
|
||||
}, (error: any) => fulfill({ error }));
|
||||
return promise;
|
||||
|
||||
function onData(chunk: string) {
|
||||
@ -165,8 +165,8 @@ export function spawnAsync(cmd: string, args: string[], options?: SpawnOptions):
|
||||
process.stdout.on('data', data => stdout += data);
|
||||
if (process.stderr)
|
||||
process.stderr.on('data', data => stderr += data);
|
||||
process.on('close', code => resolve({stdout, stderr, code}));
|
||||
process.on('error', error => resolve({stdout, stderr, code: 0, error}));
|
||||
process.on('close', code => resolve({ stdout, stderr, code }));
|
||||
process.on('error', error => resolve({ stdout, stderr, code: 0, error }));
|
||||
});
|
||||
}
|
||||
|
||||
@ -265,7 +265,7 @@ export function getAsBooleanFromENV(name: string): boolean {
|
||||
|
||||
export async function mkdirIfNeeded(filePath: string) {
|
||||
// This will harmlessly throw on windows if the dirname is the root directory.
|
||||
await fs.promises.mkdir(path.dirname(filePath), {recursive: true}).catch(() => {});
|
||||
await fs.promises.mkdir(path.dirname(filePath), { recursive: true }).catch(() => {});
|
||||
}
|
||||
|
||||
type HeadersArray = { name: string, value: string }[];
|
||||
@ -326,7 +326,7 @@ export function arrayToObject(array?: NameValue[]): { [key: string]: string } |
|
||||
if (!array)
|
||||
return undefined;
|
||||
const result: { [key: string]: string } = {};
|
||||
for (const {name, value} of array)
|
||||
for (const { name, value } of array)
|
||||
result[name] = value;
|
||||
return result;
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ export const Expandable: React.FunctionComponent<{
|
||||
<div className='expandable-title' style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', whiteSpace: 'nowrap' }}>
|
||||
<div
|
||||
className={'codicon codicon-' + (expanded ? 'chevron-down' : 'chevron-right')}
|
||||
style={{ cursor: 'pointer', color: 'var(--color)', marginRight: '4px'}}
|
||||
style={{ cursor: 'pointer', color: 'var(--color)', marginRight: '4px' }}
|
||||
onClick={() => setExpanded(!expanded)} />
|
||||
{title}
|
||||
</div>
|
||||
|
@ -53,7 +53,7 @@ export const SplitView: React.FC<SplitViewProps> = ({
|
||||
|
||||
return <div className={'split-view ' + orientation + (sidebarIsFirst ? ' sidebar-first' : '') }>
|
||||
<div className='split-view-main'>{childrenArray[0]}</div>
|
||||
{ !sidebarHidden && <div style={{flexBasis: size}} className='split-view-sidebar'>{childrenArray[1]}</div> }
|
||||
{ !sidebarHidden && <div style={{ flexBasis: size }} className='split-view-sidebar'>{childrenArray[1]}</div> }
|
||||
{ !sidebarHidden && <div
|
||||
style={resizerStyle}
|
||||
className='split-view-resizer'
|
||||
|
@ -233,7 +233,7 @@ const StepTreeItem: React.FC<{
|
||||
const StatsView: React.FC<{
|
||||
stats: Stats
|
||||
}> = ({ stats }) => {
|
||||
return <div className='hbox' style={{flex: 'none'}}>
|
||||
return <div className='hbox' style={{ flex: 'none' }}>
|
||||
{!!stats.expected && <div className='stats expected' title='Passed'>{stats.expected}</div>}
|
||||
{!!stats.unexpected && <div className='stats unexpected' title='Failed'>{stats.unexpected}</div>}
|
||||
{!!stats.flaky && <div className='stats flaky' title='Flaky'>{stats.flaky}</div>}
|
||||
|
@ -32,7 +32,7 @@ export const CallLogView: React.FC<CallLogProps> = ({
|
||||
if (log.find(callLog => callLog.reveal))
|
||||
messagesEndRef.current?.scrollIntoView({ block: 'center', inline: 'nearest' });
|
||||
}, [messagesEndRef, log]);
|
||||
return <div className='call-log' style={{flex: 'auto'}}>
|
||||
return <div className='call-log' style={{ flex: 'auto' }}>
|
||||
{log.map(callLog => {
|
||||
const expandOverride = expandOverrides.get(callLog.id);
|
||||
const isExpanded = typeof expandOverride === 'boolean' ? expandOverride : callLog.status !== 'done';
|
||||
|
@ -81,7 +81,7 @@ export const Recorder: React.FC<RecorderProps> = ({
|
||||
return <div className='recorder'>
|
||||
<Toolbar>
|
||||
<ToolbarButton icon='record' title='Record' toggled={mode === 'recording'} onClick={() => {
|
||||
window.dispatch({ event: 'setMode', params: { mode: mode === 'recording' ? 'none' : 'recording' }});
|
||||
window.dispatch({ event: 'setMode', params: { mode: mode === 'recording' ? 'none' : 'recording' } });
|
||||
}}>Record</ToolbarButton>
|
||||
<ToolbarButton icon='files' title='Copy' disabled={!source || !source.text} onClick={() => {
|
||||
copy(source.text);
|
||||
@ -95,7 +95,7 @@ export const Recorder: React.FC<RecorderProps> = ({
|
||||
<ToolbarButton icon='debug-step-over' title='Step over' disabled={!paused} onClick={() => {
|
||||
window.dispatch({ event: 'step' });
|
||||
}}></ToolbarButton>
|
||||
<div style={{flex: 'auto'}}></div>
|
||||
<div style={{ flex: 'auto' }}></div>
|
||||
<div>Target:</div>
|
||||
<select className='recorder-chooser' hidden={!sources.length} value={file} onChange={event => {
|
||||
setFile(event.target.selectedOptions[0].value);
|
||||
@ -115,7 +115,7 @@ export const Recorder: React.FC<RecorderProps> = ({
|
||||
<div className='vbox'>
|
||||
<Toolbar>
|
||||
<ToolbarButton icon='microscope' title='Explore' toggled={mode === 'inspecting'} onClick={() => {
|
||||
window.dispatch({ event: 'setMode', params: { mode: mode === 'inspecting' ? 'none' : 'inspecting' }}).catch(() => { });
|
||||
window.dispatch({ event: 'setMode', params: { mode: mode === 'inspecting' ? 'none' : 'inspecting' } }).catch(() => { });
|
||||
}}>Explore</ToolbarButton>
|
||||
<input ref={selectorInputRef} className='selector-input' placeholder='Playwright Selector' value={selector} disabled={mode !== 'none'} onChange={event => {
|
||||
setSelector(event.target.value);
|
||||
|
@ -52,6 +52,6 @@ test('should be able to send CDP messages', async ({ androidDevice }) => {
|
||||
const [page] = context.pages();
|
||||
const client = await context.newCDPSession(page);
|
||||
await client.send('Runtime.enable');
|
||||
const evalResponse = await client.send('Runtime.evaluate', {expression: '1 + 2', returnByValue: true});
|
||||
const evalResponse = await client.send('Runtime.evaluate', { expression: '1 + 2', returnByValue: true });
|
||||
expect(evalResponse.result.value).toBe(3);
|
||||
});
|
||||
|
@ -38,7 +38,7 @@ test('androidDevice.screenshot', async function({ androidDevice }, testInfo) {
|
||||
const result = await androidDevice.screenshot({ path });
|
||||
const buffer = fs.readFileSync(path);
|
||||
expect(result.length).toBe(buffer.length);
|
||||
const { width, height} = PNG.sync.read(result);
|
||||
const { width, height } = PNG.sync.read(result);
|
||||
expect(width).toBe(1080);
|
||||
expect(height).toBe(1920);
|
||||
});
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import { contextTest as it, expect } from './config/browserTest';
|
||||
|
||||
it('should close browser with beforeunload page', async ({server, browserType, browserOptions }) => {
|
||||
it('should close browser with beforeunload page', async ({ server, browserType, browserOptions }) => {
|
||||
const browser = await browserType.launch(browserOptions);
|
||||
const page = await browser.newPage();
|
||||
await page.goto(server.PREFIX + '/beforeunload.html');
|
||||
@ -27,7 +27,7 @@ it('should close browser with beforeunload page', async ({server, browserType, b
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should close browsercontext with beforeunload page', async ({server, page, context }) => {
|
||||
it('should close browsercontext with beforeunload page', async ({ server, page, context }) => {
|
||||
await page.goto(server.PREFIX + '/beforeunload.html');
|
||||
// We have to interact with a page so that 'beforeunload' handlers
|
||||
// fire.
|
||||
@ -35,7 +35,7 @@ it('should close browsercontext with beforeunload page', async ({server, page, c
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should be able to navigate away from page with beforeunload', async ({server, page, context }) => {
|
||||
it('should be able to navigate away from page with beforeunload', async ({ server, page, context }) => {
|
||||
await page.goto(server.PREFIX + '/beforeunload.html');
|
||||
// We have to interact with a page so that 'beforeunload' handlers
|
||||
// fire.
|
||||
@ -43,7 +43,7 @@ it('should be able to navigate away from page with beforeunload', async ({server
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
});
|
||||
|
||||
it('should close page with beforeunload listener', async ({context, server}) => {
|
||||
it('should close page with beforeunload listener', async ({ context, server }) => {
|
||||
const newPage = await context.newPage();
|
||||
await newPage.goto(server.PREFIX + '/beforeunload.html');
|
||||
// We have to interact with a page so that 'beforeunload' handlers
|
||||
@ -52,7 +52,7 @@ it('should close page with beforeunload listener', async ({context, server}) =>
|
||||
await newPage.close();
|
||||
});
|
||||
|
||||
it('should run beforeunload if asked for', async ({context, server, browserName}) => {
|
||||
it('should run beforeunload if asked for', async ({ context, server, browserName }) => {
|
||||
const newPage = await context.newPage();
|
||||
await newPage.goto(server.PREFIX + '/beforeunload.html');
|
||||
// We have to interact with a page so that 'beforeunload' handlers
|
||||
@ -76,7 +76,7 @@ it('should run beforeunload if asked for', async ({context, server, browserName}
|
||||
]);
|
||||
});
|
||||
|
||||
it('should access page after beforeunload', async ({page, server}) => {
|
||||
it('should access page after beforeunload', async ({ page, server }) => {
|
||||
await page.goto(server.PREFIX + '/beforeunload.html');
|
||||
// We have to interact with a page so that 'beforeunload' handlers
|
||||
// fire.
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
import { browserTest as test, expect } from './config/browserTest';
|
||||
|
||||
test('should create new page', async function({browser}) {
|
||||
test('should create new page', async function({ browser }) {
|
||||
const page1 = await browser.newPage();
|
||||
expect(browser.contexts().length).toBe(1);
|
||||
|
||||
@ -30,7 +30,7 @@ test('should create new page', async function({browser}) {
|
||||
expect(browser.contexts().length).toBe(0);
|
||||
});
|
||||
|
||||
test('should throw upon second create new page', async function({browser}) {
|
||||
test('should throw upon second create new page', async function({ browser }) {
|
||||
const page = await browser.newPage();
|
||||
let error;
|
||||
await page.context().newPage().catch(e => error = e);
|
||||
@ -38,7 +38,7 @@ test('should throw upon second create new page', async function({browser}) {
|
||||
expect(error.message).toContain('Please use browser.newContext()');
|
||||
});
|
||||
|
||||
test('version should work', async function({browser, browserName}) {
|
||||
test('version should work', async function({ browser, browserName }) {
|
||||
const version = browser.version();
|
||||
if (browserName === 'chromium')
|
||||
expect(version.match(/^\d+\.\d+\.\d+\.\d+$/)).toBeTruthy();
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import { contextTest as it, playwrightTest, expect } from './config/browserTest';
|
||||
|
||||
it('should work', async ({context, page, server}) => {
|
||||
it('should work', async ({ context, page, server }) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await context.addCookies([{
|
||||
url: server.EMPTY_PAGE,
|
||||
@ -27,7 +27,7 @@ it('should work', async ({context, page, server}) => {
|
||||
expect(await page.evaluate(() => document.cookie)).toEqual('password=123456');
|
||||
});
|
||||
|
||||
it('should work with expires=-1', async ({context, page}) => {
|
||||
it('should work with expires=-1', async ({ context, page }) => {
|
||||
await context.addCookies([{
|
||||
name: 'username',
|
||||
value: 'John Doe',
|
||||
@ -45,7 +45,7 @@ it('should work with expires=-1', async ({context, page}) => {
|
||||
expect(await page.evaluate(() => document.cookie)).toEqual('username=John Doe');
|
||||
});
|
||||
|
||||
it('should roundtrip cookie', async ({context, page, server}) => {
|
||||
it('should roundtrip cookie', async ({ context, page, server }) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
// @see https://en.wikipedia.org/wiki/Year_2038_problem
|
||||
const date = +(new Date('1/1/2038'));
|
||||
@ -62,22 +62,22 @@ it('should roundtrip cookie', async ({context, page, server}) => {
|
||||
expect(await context.cookies()).toEqual(cookies);
|
||||
});
|
||||
|
||||
it('should send cookie header', async ({server, context}) => {
|
||||
it('should send cookie header', async ({ server, context }) => {
|
||||
let cookie = '';
|
||||
server.setRoute('/empty.html', (req, res) => {
|
||||
cookie = req.headers.cookie;
|
||||
res.end();
|
||||
});
|
||||
await context.addCookies([{url: server.EMPTY_PAGE, name: 'cookie', value: 'value'}]);
|
||||
await context.addCookies([{ url: server.EMPTY_PAGE, name: 'cookie', value: 'value' }]);
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
expect(cookie).toBe('cookie=value');
|
||||
});
|
||||
|
||||
it('should isolate cookies in browser contexts', async ({context, server, browser}) => {
|
||||
it('should isolate cookies in browser contexts', async ({ context, server, browser }) => {
|
||||
const anotherContext = await browser.newContext();
|
||||
await context.addCookies([{url: server.EMPTY_PAGE, name: 'isolatecookie', value: 'page1value'}]);
|
||||
await anotherContext.addCookies([{url: server.EMPTY_PAGE, name: 'isolatecookie', value: 'page2value'}]);
|
||||
await context.addCookies([{ url: server.EMPTY_PAGE, name: 'isolatecookie', value: 'page1value' }]);
|
||||
await anotherContext.addCookies([{ url: server.EMPTY_PAGE, name: 'isolatecookie', value: 'page2value' }]);
|
||||
|
||||
const cookies1 = await context.cookies();
|
||||
const cookies2 = await anotherContext.cookies();
|
||||
@ -90,7 +90,7 @@ it('should isolate cookies in browser contexts', async ({context, server, browse
|
||||
await anotherContext.close();
|
||||
});
|
||||
|
||||
it('should isolate session cookies', async ({context, server, browser}) => {
|
||||
it('should isolate session cookies', async ({ context, server, browser }) => {
|
||||
server.setRoute('/setcookie.html', (req, res) => {
|
||||
res.setHeader('Set-Cookie', 'session=value');
|
||||
res.end();
|
||||
@ -116,7 +116,7 @@ it('should isolate session cookies', async ({context, server, browser}) => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should isolate persistent cookies', async ({context, server, browser}) => {
|
||||
it('should isolate persistent cookies', async ({ context, server, browser }) => {
|
||||
server.setRoute('/setcookie.html', (req, res) => {
|
||||
res.setHeader('Set-Cookie', 'persistent=persistent-value; max-age=3600');
|
||||
res.end();
|
||||
@ -136,13 +136,13 @@ it('should isolate persistent cookies', async ({context, server, browser}) => {
|
||||
await context2.close();
|
||||
});
|
||||
|
||||
it('should isolate send cookie header', async ({server, context, browser}) => {
|
||||
it('should isolate send cookie header', async ({ server, context, browser }) => {
|
||||
let cookie = '';
|
||||
server.setRoute('/empty.html', (req, res) => {
|
||||
cookie = req.headers.cookie || '';
|
||||
res.end();
|
||||
});
|
||||
await context.addCookies([{url: server.EMPTY_PAGE, name: 'sendcookie', value: 'value'}]);
|
||||
await context.addCookies([{ url: server.EMPTY_PAGE, name: 'sendcookie', value: 'value' }]);
|
||||
{
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -157,12 +157,12 @@ it('should isolate send cookie header', async ({server, context, browser}) => {
|
||||
}
|
||||
});
|
||||
|
||||
playwrightTest('should isolate cookies between launches', async ({browserType, server, browserOptions}) => {
|
||||
playwrightTest('should isolate cookies between launches', async ({ browserType, server, browserOptions }) => {
|
||||
playwrightTest.slow();
|
||||
|
||||
const browser1 = await browserType.launch(browserOptions);
|
||||
const context1 = await browser1.newContext();
|
||||
await context1.addCookies([{url: server.EMPTY_PAGE, name: 'cookie-in-context-1', value: 'value', expires: Date.now() / 1000 + 10000}]);
|
||||
await context1.addCookies([{ url: server.EMPTY_PAGE, name: 'cookie-in-context-1', value: 'value', expires: Date.now() / 1000 + 10000 }]);
|
||||
await browser1.close();
|
||||
|
||||
const browser2 = await browserType.launch(browserOptions);
|
||||
@ -172,7 +172,7 @@ playwrightTest('should isolate cookies between launches', async ({browserType, s
|
||||
await browser2.close();
|
||||
});
|
||||
|
||||
it('should set multiple cookies', async ({context, page, server}) => {
|
||||
it('should set multiple cookies', async ({ context, page, server }) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await context.addCookies([{
|
||||
url: server.EMPTY_PAGE,
|
||||
@ -192,7 +192,7 @@ it('should set multiple cookies', async ({context, page, server}) => {
|
||||
]);
|
||||
});
|
||||
|
||||
it('should have |expires| set to |-1| for session cookies', async ({context, server}) => {
|
||||
it('should have |expires| set to |-1| for session cookies', async ({ context, server }) => {
|
||||
await context.addCookies([{
|
||||
url: server.EMPTY_PAGE,
|
||||
name: 'expires',
|
||||
@ -202,7 +202,7 @@ it('should have |expires| set to |-1| for session cookies', async ({context, ser
|
||||
expect(cookies[0].expires).toBe(-1);
|
||||
});
|
||||
|
||||
it('should set cookie with reasonable defaults', async ({context, server, browserName}) => {
|
||||
it('should set cookie with reasonable defaults', async ({ context, server, browserName }) => {
|
||||
await context.addCookies([{
|
||||
url: server.EMPTY_PAGE,
|
||||
name: 'defaults',
|
||||
@ -221,7 +221,7 @@ it('should set cookie with reasonable defaults', async ({context, server, browse
|
||||
}]);
|
||||
});
|
||||
|
||||
it('should set a cookie with a path', async ({context, page, server, browserName, isWindows}) => {
|
||||
it('should set a cookie with a path', async ({ context, page, server, browserName, isWindows }) => {
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
await context.addCookies([{
|
||||
domain: 'localhost',
|
||||
@ -247,12 +247,12 @@ it('should set a cookie with a path', async ({context, page, server, browserName
|
||||
expect(await page.evaluate('document.cookie')).toBe('gridcookie=GRID');
|
||||
});
|
||||
|
||||
it('should not set a cookie with blank page URL', async function({context, server}) {
|
||||
it('should not set a cookie with blank page URL', async function({ context, server }) {
|
||||
let error = null;
|
||||
try {
|
||||
await context.addCookies([
|
||||
{url: server.EMPTY_PAGE, name: 'example-cookie', value: 'best'},
|
||||
{url: 'about:blank', name: 'example-cookie-blank', value: 'best'}
|
||||
{ url: server.EMPTY_PAGE, name: 'example-cookie', value: 'best' },
|
||||
{ url: 'about:blank', name: 'example-cookie-blank', value: 'best' }
|
||||
]);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
@ -262,17 +262,17 @@ it('should not set a cookie with blank page URL', async function({context, serve
|
||||
);
|
||||
});
|
||||
|
||||
it('should not set a cookie on a data URL page', async function({context}) {
|
||||
it('should not set a cookie on a data URL page', async function({ context }) {
|
||||
let error = null;
|
||||
try {
|
||||
await context.addCookies([{url: 'data:,Hello%2C%20World!', name: 'example-cookie', value: 'best'}]);
|
||||
await context.addCookies([{ url: 'data:,Hello%2C%20World!', name: 'example-cookie', value: 'best' }]);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
expect(error.message).toContain('Data URL page can not have cookie "example-cookie"');
|
||||
});
|
||||
|
||||
it('should default to setting secure cookie for HTTPS websites', async ({context, page, server}) => {
|
||||
it('should default to setting secure cookie for HTTPS websites', async ({ context, page, server }) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const SECURE_URL = 'https://example.com';
|
||||
await context.addCookies([{
|
||||
@ -284,7 +284,7 @@ it('should default to setting secure cookie for HTTPS websites', async ({context
|
||||
expect(cookie.secure).toBe(true);
|
||||
});
|
||||
|
||||
it('should be able to set unsecure cookie for HTTP website', async ({context, page, server}) => {
|
||||
it('should be able to set unsecure cookie for HTTP website', async ({ context, page, server }) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const HTTP_URL = 'http://example.com';
|
||||
await context.addCookies([{
|
||||
@ -296,7 +296,7 @@ it('should be able to set unsecure cookie for HTTP website', async ({context, pa
|
||||
expect(cookie.secure).toBe(false);
|
||||
});
|
||||
|
||||
it('should set a cookie on a different domain', async ({context, page, server, browserName, isWindows}) => {
|
||||
it('should set a cookie on a different domain', async ({ context, page, server, browserName, isWindows }) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await context.addCookies([{
|
||||
url: 'https://www.example.com',
|
||||
@ -317,10 +317,10 @@ it('should set a cookie on a different domain', async ({context, page, server, b
|
||||
}]);
|
||||
});
|
||||
|
||||
it('should set cookies for a frame', async ({context, page, server}) => {
|
||||
it('should set cookies for a frame', async ({ context, page, server }) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await context.addCookies([
|
||||
{url: server.PREFIX, name: 'frame-cookie', value: 'value'}
|
||||
{ url: server.PREFIX, name: 'frame-cookie', value: 'value' }
|
||||
]);
|
||||
await page.evaluate(src => {
|
||||
let fulfill;
|
||||
@ -335,7 +335,7 @@ it('should set cookies for a frame', async ({context, page, server}) => {
|
||||
expect(await page.frames()[1].evaluate('document.cookie')).toBe('frame-cookie=value');
|
||||
});
|
||||
|
||||
it('should(not) block third party cookies', async ({context, page, server, browserName}) => {
|
||||
it('should(not) block third party cookies', async ({ context, page, server, browserName }) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.evaluate(src => {
|
||||
let fulfill;
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import { browserTest as it, expect } from './config/browserTest';
|
||||
|
||||
it('should construct a new URL when a baseURL in browser.newContext is passed to page.goto', async function({browser, server}) {
|
||||
it('should construct a new URL when a baseURL in browser.newContext is passed to page.goto', async function({ browser, server }) {
|
||||
const context = await browser.newContext({
|
||||
baseURL: server.PREFIX,
|
||||
});
|
||||
@ -26,7 +26,7 @@ it('should construct a new URL when a baseURL in browser.newContext is passed to
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should construct a new URL when a baseURL in browser.newPage is passed to page.goto', async function({browser, server}) {
|
||||
it('should construct a new URL when a baseURL in browser.newPage is passed to page.goto', async function({ browser, server }) {
|
||||
const page = await browser.newPage({
|
||||
baseURL: server.PREFIX,
|
||||
});
|
||||
@ -34,7 +34,7 @@ it('should construct a new URL when a baseURL in browser.newPage is passed to pa
|
||||
await page.close();
|
||||
});
|
||||
|
||||
it('should construct a new URL when a baseURL in browserType.launchPersistentContext is passed to page.goto', async function({browserType, server, createUserDataDir, browserOptions}) {
|
||||
it('should construct a new URL when a baseURL in browserType.launchPersistentContext is passed to page.goto', async function({ browserType, server, createUserDataDir, browserOptions }) {
|
||||
const userDataDir = await createUserDataDir();
|
||||
const context = await browserType.launchPersistentContext(userDataDir, {
|
||||
...browserOptions,
|
||||
@ -45,7 +45,7 @@ it('should construct a new URL when a baseURL in browserType.launchPersistentCon
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should construct the URLs correctly when a baseURL without a trailing slash in browser.newPage is passed to page.goto', async function({browser, server}) {
|
||||
it('should construct the URLs correctly when a baseURL without a trailing slash in browser.newPage is passed to page.goto', async function({ browser, server }) {
|
||||
const page = await browser.newPage({
|
||||
baseURL: server.PREFIX + '/url-construction',
|
||||
});
|
||||
@ -55,7 +55,7 @@ it('should construct the URLs correctly when a baseURL without a trailing slash
|
||||
await page.close();
|
||||
});
|
||||
|
||||
it('should construct the URLs correctly when a baseURL with a trailing slash in browser.newPage is passed to page.goto', async function({browser, server}) {
|
||||
it('should construct the URLs correctly when a baseURL with a trailing slash in browser.newPage is passed to page.goto', async function({ browser, server }) {
|
||||
const page = await browser.newPage({
|
||||
baseURL: server.PREFIX + '/url-construction/',
|
||||
});
|
||||
@ -67,7 +67,7 @@ it('should construct the URLs correctly when a baseURL with a trailing slash in
|
||||
await page.close();
|
||||
});
|
||||
|
||||
it('should not construct a new URL when valid URLs are passed', async function({browser, server}) {
|
||||
it('should not construct a new URL when valid URLs are passed', async function({ browser, server }) {
|
||||
const page = await browser.newPage({
|
||||
baseURL: 'http://microsoft.com',
|
||||
});
|
||||
@ -81,7 +81,7 @@ it('should not construct a new URL when valid URLs are passed', async function({
|
||||
await page.close();
|
||||
});
|
||||
|
||||
it('should be able to match a URL relative to its given URL with urlMatcher', async function({browser, server}) {
|
||||
it('should be able to match a URL relative to its given URL with urlMatcher', async function({ browser, server }) {
|
||||
const page = await browser.newPage({
|
||||
baseURL: server.PREFIX + '/foobar/',
|
||||
});
|
||||
@ -103,7 +103,7 @@ it('should be able to match a URL relative to its given URL with urlMatcher', as
|
||||
await page.close();
|
||||
});
|
||||
|
||||
it('should not construct a new URL with baseURL when a glob was used', async function({browser, server}) {
|
||||
it('should not construct a new URL with baseURL when a glob was used', async function({ browser, server }) {
|
||||
const page = await browser.newPage({
|
||||
baseURL: server.PREFIX + '/foobar/',
|
||||
});
|
||||
|
@ -18,7 +18,7 @@
|
||||
import { browserTest as it, expect } from './config/browserTest';
|
||||
import { attachFrame, verifyViewport } from './config/utils';
|
||||
|
||||
it('should create new context', async function({browser}) {
|
||||
it('should create new context', async function({ browser }) {
|
||||
expect(browser.contexts().length).toBe(0);
|
||||
const context = await browser.newContext();
|
||||
expect(browser.contexts().length).toBe(1);
|
||||
@ -29,7 +29,7 @@ it('should create new context', async function({browser}) {
|
||||
expect(browser).toBe(context.browser());
|
||||
});
|
||||
|
||||
it('window.open should use parent tab context', async function({browser, server}) {
|
||||
it('window.open should use parent tab context', async function({ browser, server }) {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -41,7 +41,7 @@ it('window.open should use parent tab context', async function({browser, server}
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should isolate localStorage and cookies', async function({browser, server}) {
|
||||
it('should isolate localStorage and cookies', async function({ browser, server }) {
|
||||
// Create two incognito contexts.
|
||||
const context1 = await browser.newContext();
|
||||
const context2 = await browser.newContext();
|
||||
@ -132,7 +132,7 @@ it('close() should abort waitForEvent', async ({ browser }) => {
|
||||
expect(error.message).toContain('Context closed');
|
||||
});
|
||||
|
||||
it('close() should be callable twice', async ({browser}) => {
|
||||
it('close() should be callable twice', async ({ browser }) => {
|
||||
const context = await browser.newContext();
|
||||
await Promise.all([
|
||||
context.close(),
|
||||
@ -141,7 +141,7 @@ it('close() should be callable twice', async ({browser}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should pass self to close event', async ({browser}) => {
|
||||
it('should pass self to close event', async ({ browser }) => {
|
||||
const newContext = await browser.newContext();
|
||||
const [closedContext] = await Promise.all([
|
||||
newContext.waitForEvent('close'),
|
||||
@ -150,7 +150,7 @@ it('should pass self to close event', async ({browser}) => {
|
||||
expect(closedContext).toBe(newContext);
|
||||
});
|
||||
|
||||
it('should not report frameless pages on error', async ({browser, server}) => {
|
||||
it('should not report frameless pages on error', async ({ browser, server }) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
server.setRoute('/empty.html', (req, res) => {
|
||||
@ -168,7 +168,7 @@ it('should not report frameless pages on error', async ({browser, server}) => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should return all of the pages', async ({browser, server}) => {
|
||||
it('should return all of the pages', async ({ browser, server }) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
const second = await context.newPage();
|
||||
@ -179,7 +179,7 @@ it('should return all of the pages', async ({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should close all belonging pages once closing context', async function({browser}) {
|
||||
it('should close all belonging pages once closing context', async function({ browser }) {
|
||||
const context = await browser.newContext();
|
||||
await context.newPage();
|
||||
expect(context.pages().length).toBe(1);
|
||||
@ -188,7 +188,7 @@ it('should close all belonging pages once closing context', async function({brow
|
||||
expect(context.pages().length).toBe(0);
|
||||
});
|
||||
|
||||
it('should disable javascript', async ({browser, browserName}) => {
|
||||
it('should disable javascript', async ({ browser, browserName }) => {
|
||||
{
|
||||
const context = await browser.newContext({ javaScriptEnabled: false });
|
||||
const page = await context.newPage();
|
||||
@ -211,15 +211,15 @@ it('should disable javascript', async ({browser, browserName}) => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should be able to navigate after disabling javascript', async ({browser, server}) => {
|
||||
it('should be able to navigate after disabling javascript', async ({ browser, server }) => {
|
||||
const context = await browser.newContext({ javaScriptEnabled: false });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should work with offline option', async ({browser, server}) => {
|
||||
const context = await browser.newContext({offline: true});
|
||||
it('should work with offline option', async ({ browser, server }) => {
|
||||
const context = await browser.newContext({ offline: true });
|
||||
const page = await context.newPage();
|
||||
let error = null;
|
||||
await page.goto(server.EMPTY_PAGE).catch(e => error = e);
|
||||
@ -230,7 +230,7 @@ it('should work with offline option', async ({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should emulate navigator.onLine', async ({browser, server}) => {
|
||||
it('should emulate navigator.onLine', async ({ browser, server }) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
expect(await page.evaluate(() => window.navigator.onLine)).toBe(true);
|
||||
@ -241,7 +241,7 @@ it('should emulate navigator.onLine', async ({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should emulate media in popup', async ({browser, server}) => {
|
||||
it('should emulate media in popup', async ({ browser, server }) => {
|
||||
{
|
||||
const context = await browser.newContext({ colorScheme: 'dark' });
|
||||
const page = await context.newPage();
|
||||
@ -267,7 +267,7 @@ it('should emulate media in popup', async ({browser, server}) => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should emulate media in cross-process iframe', async ({browser, server}) => {
|
||||
it('should emulate media in cross-process iframe', async ({ browser, server }) => {
|
||||
const page = await browser.newPage({ colorScheme: 'dark' });
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await attachFrame(page, 'frame1', server.CROSS_PROCESS_PREFIX + '/empty.html');
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import { contextTest as it, expect } from './config/browserTest';
|
||||
|
||||
it('should clear cookies', async ({context, page, server}) => {
|
||||
it('should clear cookies', async ({ context, page, server }) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await context.addCookies([{
|
||||
url: server.EMPTY_PAGE,
|
||||
@ -31,10 +31,10 @@ it('should clear cookies', async ({context, page, server}) => {
|
||||
expect(await page.evaluate('document.cookie')).toBe('');
|
||||
});
|
||||
|
||||
it('should isolate cookies when clearing', async ({context, server, browser}) => {
|
||||
it('should isolate cookies when clearing', async ({ context, server, browser }) => {
|
||||
const anotherContext = await browser.newContext();
|
||||
await context.addCookies([{url: server.EMPTY_PAGE, name: 'page1cookie', value: 'page1value'}]);
|
||||
await anotherContext.addCookies([{url: server.EMPTY_PAGE, name: 'page2cookie', value: 'page2value'}]);
|
||||
await context.addCookies([{ url: server.EMPTY_PAGE, name: 'page1cookie', value: 'page1value' }]);
|
||||
await anotherContext.addCookies([{ url: server.EMPTY_PAGE, name: 'page2cookie', value: 'page2value' }]);
|
||||
|
||||
expect((await context.cookies()).length).toBe(1);
|
||||
expect((await anotherContext.cookies()).length).toBe(1);
|
||||
|
@ -17,11 +17,11 @@
|
||||
|
||||
import { contextTest as it, expect } from './config/browserTest';
|
||||
|
||||
it('should return no cookies in pristine browser context', async ({context, page, server}) => {
|
||||
it('should return no cookies in pristine browser context', async ({ context, page, server }) => {
|
||||
expect(await context.cookies()).toEqual([]);
|
||||
});
|
||||
|
||||
it('should get a cookie', async ({context, page, server, browserName}) => {
|
||||
it('should get a cookie', async ({ context, page, server, browserName }) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const documentCookie = await page.evaluate(() => {
|
||||
document.cookie = 'username=John Doe';
|
||||
@ -40,7 +40,7 @@ it('should get a cookie', async ({context, page, server, browserName}) => {
|
||||
}]);
|
||||
});
|
||||
|
||||
it('should get a non-session cookie', async ({context, page, server, browserName}) => {
|
||||
it('should get a non-session cookie', async ({ context, page, server, browserName }) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
// @see https://en.wikipedia.org/wiki/Year_2038_problem
|
||||
const date = +(new Date('1/1/2038'));
|
||||
@ -62,7 +62,7 @@ it('should get a non-session cookie', async ({context, page, server, browserName
|
||||
}]);
|
||||
});
|
||||
|
||||
it('should properly report httpOnly cookie', async ({context, page, server}) => {
|
||||
it('should properly report httpOnly cookie', async ({ context, page, server }) => {
|
||||
server.setRoute('/empty.html', (req, res) => {
|
||||
res.setHeader('Set-Cookie', 'name=value;HttpOnly; Path=/');
|
||||
res.end();
|
||||
@ -73,7 +73,7 @@ it('should properly report httpOnly cookie', async ({context, page, server}) =>
|
||||
expect(cookies[0].httpOnly).toBe(true);
|
||||
});
|
||||
|
||||
it('should properly report "Strict" sameSite cookie', async ({context, page, server, browserName, platform}) => {
|
||||
it('should properly report "Strict" sameSite cookie', async ({ context, page, server, browserName, platform }) => {
|
||||
it.fail(browserName === 'webkit' && platform === 'win32');
|
||||
|
||||
server.setRoute('/empty.html', (req, res) => {
|
||||
@ -86,7 +86,7 @@ it('should properly report "Strict" sameSite cookie', async ({context, page, ser
|
||||
expect(cookies[0].sameSite).toBe('Strict');
|
||||
});
|
||||
|
||||
it('should properly report "Lax" sameSite cookie', async ({context, page, server, browserName, platform}) => {
|
||||
it('should properly report "Lax" sameSite cookie', async ({ context, page, server, browserName, platform }) => {
|
||||
it.fail(browserName === 'webkit' && platform === 'win32');
|
||||
|
||||
server.setRoute('/empty.html', (req, res) => {
|
||||
@ -99,7 +99,7 @@ it('should properly report "Lax" sameSite cookie', async ({context, page, server
|
||||
expect(cookies[0].sameSite).toBe('Lax');
|
||||
});
|
||||
|
||||
it('should get multiple cookies', async ({context, page, server, browserName}) => {
|
||||
it('should get multiple cookies', async ({ context, page, server, browserName }) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const documentCookie = await page.evaluate(() => {
|
||||
document.cookie = 'username=John Doe';
|
||||
@ -132,7 +132,7 @@ it('should get multiple cookies', async ({context, page, server, browserName}) =
|
||||
]));
|
||||
});
|
||||
|
||||
it('should get cookies from multiple urls', async ({context, browserName, isWindows}) => {
|
||||
it('should get cookies from multiple urls', async ({ context, browserName, isWindows }) => {
|
||||
await context.addCookies([{
|
||||
url: 'https://foo.com',
|
||||
name: 'doggo',
|
||||
@ -171,7 +171,7 @@ it('should get cookies from multiple urls', async ({context, browserName, isWind
|
||||
}]));
|
||||
});
|
||||
|
||||
it('should work with subdomain cookie', async ({context, browserName, isWindows}) => {
|
||||
it('should work with subdomain cookie', async ({ context, browserName, isWindows }) => {
|
||||
await context.addCookies([{
|
||||
domain: '.foo.com',
|
||||
path: '/',
|
||||
@ -202,7 +202,7 @@ it('should work with subdomain cookie', async ({context, browserName, isWindows}
|
||||
}]);
|
||||
});
|
||||
|
||||
it('should not return cookies with empty value', async ({context, page, server}) => {
|
||||
it('should not return cookies with empty value', async ({ context, page, server }) => {
|
||||
server.setRoute('/empty.html', (req, res) => {
|
||||
res.setHeader('Set-Cookie', 'name=;Path=/');
|
||||
res.end();
|
||||
@ -212,7 +212,7 @@ it('should not return cookies with empty value', async ({context, page, server})
|
||||
expect(cookies.length).toBe(0);
|
||||
});
|
||||
|
||||
it('should return secure cookies based on HTTP(S) protocol', async ({context, browserName, isWindows}) => {
|
||||
it('should return secure cookies based on HTTP(S) protocol', async ({ context, browserName, isWindows }) => {
|
||||
await context.addCookies([{
|
||||
url: 'https://foo.com',
|
||||
name: 'doggo',
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import { browserTest as it, expect } from './config/browserTest';
|
||||
|
||||
it('should fail without credentials', async ({browser, server, browserName, headless}) => {
|
||||
it('should fail without credentials', async ({ browser, server, browserName, headless }) => {
|
||||
it.fail(browserName === 'chromium' && !headless);
|
||||
|
||||
server.setAuth('/empty.html', 'user', 'pass');
|
||||
@ -28,7 +28,7 @@ it('should fail without credentials', async ({browser, server, browserName, head
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should work with setHTTPCredentials', async ({browser, server, browserName, headless}) => {
|
||||
it('should work with setHTTPCredentials', async ({ browser, server, browserName, headless }) => {
|
||||
it.fail(browserName === 'chromium' && !headless);
|
||||
|
||||
server.setAuth('/empty.html', 'user', 'pass');
|
||||
@ -42,7 +42,7 @@ it('should work with setHTTPCredentials', async ({browser, server, browserName,
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should work with correct credentials', async ({browser, server}) => {
|
||||
it('should work with correct credentials', async ({ browser, server }) => {
|
||||
server.setAuth('/empty.html', 'user', 'pass');
|
||||
const context = await browser.newContext({
|
||||
httpCredentials: { username: 'user', password: 'pass' }
|
||||
@ -53,7 +53,7 @@ it('should work with correct credentials', async ({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should fail with wrong credentials', async ({browser, server}) => {
|
||||
it('should fail with wrong credentials', async ({ browser, server }) => {
|
||||
server.setAuth('/empty.html', 'user', 'pass');
|
||||
const context = await browser.newContext({
|
||||
httpCredentials: { username: 'foo', password: 'bar' }
|
||||
@ -64,7 +64,7 @@ it('should fail with wrong credentials', async ({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should return resource body', async ({browser, server}) => {
|
||||
it('should return resource body', async ({ browser, server }) => {
|
||||
server.setAuth('/playground.html', 'user', 'pass');
|
||||
const context = await browser.newContext({
|
||||
httpCredentials: { username: 'user', password: 'pass' }
|
||||
|
@ -18,13 +18,13 @@
|
||||
import { browserTest as it, expect } from './config/browserTest';
|
||||
import { attachFrame } from './config/utils';
|
||||
|
||||
it('should bypass CSP meta tag', async ({browser, server}) => {
|
||||
it('should bypass CSP meta tag', async ({ browser, server }) => {
|
||||
// Make sure CSP prohibits addScriptTag.
|
||||
{
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.PREFIX + '/csp.html');
|
||||
await page.addScriptTag({content: 'window["__injected"] = 42;'}).catch(e => void e);
|
||||
await page.addScriptTag({ content: 'window["__injected"] = 42;' }).catch(e => void e);
|
||||
expect(await page.evaluate('window["__injected"]')).toBe(undefined);
|
||||
await context.close();
|
||||
}
|
||||
@ -34,13 +34,13 @@ it('should bypass CSP meta tag', async ({browser, server}) => {
|
||||
const context = await browser.newContext({ bypassCSP: true });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.PREFIX + '/csp.html');
|
||||
await page.addScriptTag({content: 'window["__injected"] = 42;'});
|
||||
await page.addScriptTag({ content: 'window["__injected"] = 42;' });
|
||||
expect(await page.evaluate('window["__injected"]')).toBe(42);
|
||||
await context.close();
|
||||
}
|
||||
});
|
||||
|
||||
it('should bypass CSP header', async ({browser, server}) => {
|
||||
it('should bypass CSP header', async ({ browser, server }) => {
|
||||
// Make sure CSP prohibits addScriptTag.
|
||||
server.setCSP('/empty.html', 'default-src "self"');
|
||||
|
||||
@ -48,7 +48,7 @@ it('should bypass CSP header', async ({browser, server}) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.addScriptTag({content: 'window["__injected"] = 42;'}).catch(e => void e);
|
||||
await page.addScriptTag({ content: 'window["__injected"] = 42;' }).catch(e => void e);
|
||||
expect(await page.evaluate('window["__injected"]')).toBe(undefined);
|
||||
await context.close();
|
||||
}
|
||||
@ -58,33 +58,33 @@ it('should bypass CSP header', async ({browser, server}) => {
|
||||
const context = await browser.newContext({ bypassCSP: true });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.addScriptTag({content: 'window["__injected"] = 42;'});
|
||||
await page.addScriptTag({ content: 'window["__injected"] = 42;' });
|
||||
expect(await page.evaluate('window["__injected"]')).toBe(42);
|
||||
await context.close();
|
||||
}
|
||||
});
|
||||
|
||||
it('should bypass after cross-process navigation', async ({browser, server}) => {
|
||||
it('should bypass after cross-process navigation', async ({ browser, server }) => {
|
||||
const context = await browser.newContext({ bypassCSP: true });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.PREFIX + '/csp.html');
|
||||
await page.addScriptTag({content: 'window["__injected"] = 42;'});
|
||||
await page.addScriptTag({ content: 'window["__injected"] = 42;' });
|
||||
expect(await page.evaluate('window["__injected"]')).toBe(42);
|
||||
|
||||
await page.goto(server.CROSS_PROCESS_PREFIX + '/csp.html');
|
||||
await page.addScriptTag({content: 'window["__injected"] = 42;'});
|
||||
await page.addScriptTag({ content: 'window["__injected"] = 42;' });
|
||||
expect(await page.evaluate('window["__injected"]')).toBe(42);
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should bypass CSP in iframes as well', async ({browser, server}) => {
|
||||
it('should bypass CSP in iframes as well', async ({ browser, server }) => {
|
||||
// Make sure CSP prohibits addScriptTag in an iframe.
|
||||
{
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const frame = await attachFrame(page, 'frame1', server.PREFIX + '/csp.html');
|
||||
await frame.addScriptTag({content: 'window["__injected"] = 42;'}).catch(e => void e);
|
||||
await frame.addScriptTag({ content: 'window["__injected"] = 42;' }).catch(e => void e);
|
||||
expect(await frame.evaluate('window["__injected"]')).toBe(undefined);
|
||||
await context.close();
|
||||
}
|
||||
@ -95,7 +95,7 @@ it('should bypass CSP in iframes as well', async ({browser, server}) => {
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const frame = await attachFrame(page, 'frame1', server.PREFIX + '/csp.html');
|
||||
await frame.addScriptTag({content: 'window["__injected"] = 42;'}).catch(e => void e);
|
||||
await frame.addScriptTag({ content: 'window["__injected"] = 42;' }).catch(e => void e);
|
||||
expect(await frame.evaluate('window["__injected"]')).toBe(42);
|
||||
await context.close();
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ import { browserTest as it, expect } from './config/browserTest';
|
||||
it.describe('device', () => {
|
||||
it.skip(({ browserName }) => browserName === 'firefox');
|
||||
|
||||
it('should work', async ({playwright, browser, server}) => {
|
||||
it('should work', async ({ playwright, browser, server }) => {
|
||||
const iPhone = playwright.devices['iPhone 6'];
|
||||
const context = await browser.newContext({ ...iPhone });
|
||||
const page = await context.newPage();
|
||||
@ -30,7 +30,7 @@ it.describe('device', () => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should support clicking', async ({playwright, browser, server}) => {
|
||||
it('should support clicking', async ({ playwright, browser, server }) => {
|
||||
const iPhone = playwright.devices['iPhone 6'];
|
||||
const context = await browser.newContext({ ...iPhone });
|
||||
const page = await context.newPage();
|
||||
@ -42,7 +42,7 @@ it.describe('device', () => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should scroll to click', async ({browser, server, contextOptions}) => {
|
||||
it('should scroll to click', async ({ browser, server, contextOptions }) => {
|
||||
const context = await browser.newContext({
|
||||
...contextOptions,
|
||||
viewport: {
|
||||
@ -60,7 +60,7 @@ it.describe('device', () => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should scroll twice when emulated', async ({server, contextFactory, playwright}) => {
|
||||
it('should scroll twice when emulated', async ({ server, contextFactory, playwright }) => {
|
||||
const device = playwright.devices['iPhone 6'];
|
||||
const context = await contextFactory(device);
|
||||
const page = await context.newPage();
|
||||
@ -78,7 +78,7 @@ it.describe('device', () => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should reset scroll top after a navigation', async ({server, contextFactory, playwright, browserName}) => {
|
||||
it('should reset scroll top after a navigation', async ({ server, contextFactory, playwright, browserName }) => {
|
||||
it.skip(browserName === 'webkit');
|
||||
|
||||
const device = playwright.devices['iPhone 6'];
|
||||
@ -92,7 +92,7 @@ it.describe('device', () => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should scroll to a precise position with mobile scale', async ({server, contextFactory, playwright, browserName}) => {
|
||||
it('should scroll to a precise position with mobile scale', async ({ server, contextFactory, playwright, browserName }) => {
|
||||
it.skip(browserName === 'webkit');
|
||||
|
||||
const device = playwright.devices['iPhone 6'];
|
||||
@ -105,7 +105,7 @@ it.describe('device', () => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should emulate viewport and screen size', async ({server, contextFactory, playwright}) => {
|
||||
it('should emulate viewport and screen size', async ({ server, contextFactory, playwright }) => {
|
||||
const device = playwright.devices['iPhone 12'];
|
||||
const context = await contextFactory(device);
|
||||
const page = await context.newPage();
|
||||
@ -124,7 +124,7 @@ it.describe('device', () => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should emulate viewport without screen size', async ({server, contextFactory, playwright}) => {
|
||||
it('should emulate viewport without screen size', async ({ server, contextFactory, playwright }) => {
|
||||
const device = playwright.devices['iPhone 6'];
|
||||
const context = await contextFactory(device);
|
||||
const page = await context.newPage();
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
import { browserTest as it, expect } from './config/browserTest';
|
||||
|
||||
it('should fetch lodpi assets', async ({ contextFactory, server}) => {
|
||||
it('should fetch lodpi assets', async ({ contextFactory, server }) => {
|
||||
const context = await contextFactory({
|
||||
deviceScaleFactor: 1
|
||||
});
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import { contextTest as it, expect } from './config/browserTest';
|
||||
|
||||
it('expose binding should work', async ({context}) => {
|
||||
it('expose binding should work', async ({ context }) => {
|
||||
let bindingSource;
|
||||
await context.exposeBinding('add', (source, a, b) => {
|
||||
bindingSource = source;
|
||||
@ -31,7 +31,7 @@ it('expose binding should work', async ({context}) => {
|
||||
expect(result).toEqual(11);
|
||||
});
|
||||
|
||||
it('should work', async ({context, server}) => {
|
||||
it('should work', async ({ context, server }) => {
|
||||
await context.exposeFunction('add', (a, b) => a + b);
|
||||
const page = await context.newPage();
|
||||
await page.exposeFunction('mul', (a, b) => a * b);
|
||||
@ -44,7 +44,7 @@ it('should work', async ({context, server}) => {
|
||||
expect(result).toEqual({ mul: 36, add: 13, sub: 5, addHandle: 11 });
|
||||
});
|
||||
|
||||
it('should throw for duplicate registrations', async ({context, server}) => {
|
||||
it('should throw for duplicate registrations', async ({ context, server }) => {
|
||||
await context.exposeFunction('foo', () => {});
|
||||
await context.exposeFunction('bar', () => {});
|
||||
let error = await context.exposeFunction('foo', () => {}).catch(e => e);
|
||||
@ -57,7 +57,7 @@ it('should throw for duplicate registrations', async ({context, server}) => {
|
||||
expect(error.message).toContain('Function "baz" has been already registered in one of the pages');
|
||||
});
|
||||
|
||||
it('should be callable from-inside addInitScript', async ({context, server}) => {
|
||||
it('should be callable from-inside addInitScript', async ({ context, server }) => {
|
||||
let args = [];
|
||||
await context.exposeFunction('woof', function(arg) {
|
||||
args.push(arg);
|
||||
@ -72,7 +72,7 @@ it('should be callable from-inside addInitScript', async ({context, server}) =>
|
||||
expect(args).toEqual(['context', 'page']);
|
||||
});
|
||||
|
||||
it('exposeBindingHandle should work', async ({context}) => {
|
||||
it('exposeBindingHandle should work', async ({ context }) => {
|
||||
let target;
|
||||
await context.exposeBinding('logme', (source, t) => {
|
||||
target = t;
|
||||
|
@ -42,7 +42,7 @@ it.afterAll(() => {
|
||||
http.globalAgent = prevAgent;
|
||||
});
|
||||
|
||||
it('get should work', async ({context, server}) => {
|
||||
it('get should work', async ({ context, server }) => {
|
||||
const response = await context._request.get(server.PREFIX + '/simple.json');
|
||||
expect(response.url()).toBe(server.PREFIX + '/simple.json');
|
||||
expect(response.status()).toBe(200);
|
||||
@ -54,7 +54,7 @@ it('get should work', async ({context, server}) => {
|
||||
expect(await response.text()).toBe('{"foo": "bar"}\n');
|
||||
});
|
||||
|
||||
it('fetch should work', async ({context, server}) => {
|
||||
it('fetch should work', async ({ context, server }) => {
|
||||
const response = await context._request.fetch(server.PREFIX + '/simple.json');
|
||||
expect(response.url()).toBe(server.PREFIX + '/simple.json');
|
||||
expect(response.status()).toBe(200);
|
||||
@ -66,7 +66,7 @@ it('fetch should work', async ({context, server}) => {
|
||||
expect(await response.text()).toBe('{"foo": "bar"}\n');
|
||||
});
|
||||
|
||||
it('should throw on network error', async ({context, server}) => {
|
||||
it('should throw on network error', async ({ context, server }) => {
|
||||
server.setRoute('/test', (req, res) => {
|
||||
req.socket.destroy();
|
||||
});
|
||||
@ -74,7 +74,7 @@ it('should throw on network error', async ({context, server}) => {
|
||||
expect(error.message).toContain('socket hang up');
|
||||
});
|
||||
|
||||
it('should throw on network error after redirect', async ({context, server}) => {
|
||||
it('should throw on network error after redirect', async ({ context, server }) => {
|
||||
server.setRedirect('/redirect', '/test');
|
||||
server.setRoute('/test', (req, res) => {
|
||||
req.socket.destroy();
|
||||
@ -83,7 +83,7 @@ it('should throw on network error after redirect', async ({context, server}) =>
|
||||
expect(error.message).toContain('socket hang up');
|
||||
});
|
||||
|
||||
it('should throw on network error when sending body', async ({context, server}) => {
|
||||
it('should throw on network error when sending body', async ({ context, server }) => {
|
||||
server.setRoute('/test', (req, res) => {
|
||||
res.writeHead(200, {
|
||||
'content-length': 4096,
|
||||
@ -97,7 +97,7 @@ it('should throw on network error when sending body', async ({context, server})
|
||||
expect(error.message).toContain('Error: aborted');
|
||||
});
|
||||
|
||||
it('should throw on network error when sending body after redirect', async ({context, server}) => {
|
||||
it('should throw on network error when sending body after redirect', async ({ context, server }) => {
|
||||
server.setRedirect('/redirect', '/test');
|
||||
server.setRoute('/test', (req, res) => {
|
||||
res.writeHead(200, {
|
||||
@ -112,7 +112,7 @@ it('should throw on network error when sending body after redirect', async ({con
|
||||
expect(error.message).toContain('Error: aborted');
|
||||
});
|
||||
|
||||
it('should add session cookies to request', async ({context, server}) => {
|
||||
it('should add session cookies to request', async ({ context, server }) => {
|
||||
await context.addCookies([{
|
||||
name: 'username',
|
||||
value: 'John Doe',
|
||||
@ -131,7 +131,7 @@ it('should add session cookies to request', async ({context, server}) => {
|
||||
});
|
||||
|
||||
for (const method of ['get', 'post', 'fetch']) {
|
||||
it(`${method} should support queryParams`, async ({context, server}) => {
|
||||
it(`${method} should support queryParams`, async ({ context, server }) => {
|
||||
let request;
|
||||
const url = new URL(server.EMPTY_PAGE);
|
||||
url.searchParams.set('p1', 'v1');
|
||||
@ -151,7 +151,7 @@ for (const method of ['get', 'post', 'fetch']) {
|
||||
expect(params.get('парам2')).toEqual('знач2');
|
||||
});
|
||||
|
||||
it(`${method} should support failOnStatusCode`, async ({context, server}) => {
|
||||
it(`${method} should support failOnStatusCode`, async ({ context, server }) => {
|
||||
const error = await context._request[method](server.PREFIX + '/does-not-exist.html', {
|
||||
failOnStatusCode: true
|
||||
}).catch(e => e);
|
||||
@ -159,7 +159,7 @@ for (const method of ['get', 'post', 'fetch']) {
|
||||
});
|
||||
}
|
||||
|
||||
it('should not add context cookie if cookie header passed as a parameter', async ({context, server}) => {
|
||||
it('should not add context cookie if cookie header passed as a parameter', async ({ context, server }) => {
|
||||
await context.addCookies([{
|
||||
name: 'username',
|
||||
value: 'John Doe',
|
||||
@ -181,7 +181,7 @@ it('should not add context cookie if cookie header passed as a parameter', async
|
||||
expect(req.headers.cookie).toEqual('foo=bar');
|
||||
});
|
||||
|
||||
it('should follow redirects', async ({context, server}) => {
|
||||
it('should follow redirects', async ({ context, server }) => {
|
||||
server.setRedirect('/redirect1', '/redirect2');
|
||||
server.setRedirect('/redirect2', '/simple.json');
|
||||
await context.addCookies([{
|
||||
@ -200,10 +200,10 @@ it('should follow redirects', async ({context, server}) => {
|
||||
]);
|
||||
expect(req.headers.cookie).toEqual('username=John Doe');
|
||||
expect(response.url()).toBe(`http://www.my.playwright.dev:${server.PORT}/simple.json`);
|
||||
expect(await response.json()).toEqual({foo: 'bar'});
|
||||
expect(await response.json()).toEqual({ foo: 'bar' });
|
||||
});
|
||||
|
||||
it('should add cookies from Set-Cookie header', async ({context, page, server}) => {
|
||||
it('should add cookies from Set-Cookie header', async ({ context, page, server }) => {
|
||||
server.setRoute('/setcookie.html', (req, res) => {
|
||||
res.setHeader('Set-Cookie', ['session=value', 'foo=bar; max-age=3600']);
|
||||
res.end();
|
||||
@ -224,7 +224,7 @@ it('should add cookies from Set-Cookie header', async ({context, page, server})
|
||||
expect((await page.evaluate(() => document.cookie)).split(';').map(s => s.trim()).sort()).toEqual(['foo=bar', 'session=value']);
|
||||
});
|
||||
|
||||
it('should not lose body while handling Set-Cookie header', async ({context, server}) => {
|
||||
it('should not lose body while handling Set-Cookie header', async ({ context, server }) => {
|
||||
server.setRoute('/setcookie.html', (req, res) => {
|
||||
res.setHeader('Set-Cookie', ['session=value', 'foo=bar; max-age=3600']);
|
||||
res.end('text content');
|
||||
@ -233,7 +233,7 @@ it('should not lose body while handling Set-Cookie header', async ({context, ser
|
||||
expect(await response.text()).toBe('text content');
|
||||
});
|
||||
|
||||
it('should handle cookies on redirects', async ({context, server, browserName, isWindows}) => {
|
||||
it('should handle cookies on redirects', async ({ context, server, browserName, isWindows }) => {
|
||||
server.setRoute('/redirect1', (req, res) => {
|
||||
res.setHeader('Set-Cookie', 'r1=v1;SameSite=Lax');
|
||||
res.writeHead(301, { location: '/a/b/redirect2' });
|
||||
@ -291,7 +291,7 @@ it('should handle cookies on redirects', async ({context, server, browserName, i
|
||||
]));
|
||||
});
|
||||
|
||||
it('should return raw headers', async ({context, page, server}) => {
|
||||
it('should return raw headers', async ({ context, page, server }) => {
|
||||
server.setRoute('/headers', (req, res) => {
|
||||
// Headers array is only supported since Node v14.14.0 so we write directly to the socket.
|
||||
// res.writeHead(200, ['name-a', 'v1','name-b', 'v4','Name-a', 'v2', 'name-A', 'v3']);
|
||||
@ -314,7 +314,7 @@ it('should return raw headers', async ({context, page, server}) => {
|
||||
expect(response.headers()['name-b']).toBe('v4');
|
||||
});
|
||||
|
||||
it('should work with context level proxy', async ({browserOptions, browserType, contextOptions, server, proxyServer}) => {
|
||||
it('should work with context level proxy', async ({ browserOptions, browserType, contextOptions, server, proxyServer }) => {
|
||||
server.setRoute('/target.html', async (req, res) => {
|
||||
res.end('<title>Served by the proxy</title>');
|
||||
});
|
||||
@ -342,7 +342,7 @@ it('should work with context level proxy', async ({browserOptions, browserType,
|
||||
}
|
||||
});
|
||||
|
||||
it('should pass proxy credentials', async ({browserType, browserOptions, server, proxyServer}) => {
|
||||
it('should pass proxy credentials', async ({ browserType, browserOptions, server, proxyServer }) => {
|
||||
proxyServer.forwardTo(server.PORT);
|
||||
let auth;
|
||||
proxyServer.setAuthHandler(req => {
|
||||
@ -357,11 +357,11 @@ it('should pass proxy credentials', async ({browserType, browserOptions, server,
|
||||
const response = await context._request.get('http://non-existent.com/simple.json');
|
||||
expect(proxyServer.connectHosts).toContain('non-existent.com:80');
|
||||
expect(auth).toBe('Basic ' + Buffer.from('user:secret').toString('base64'));
|
||||
expect(await response.json()).toEqual({foo: 'bar'});
|
||||
expect(await response.json()).toEqual({ foo: 'bar' });
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should work with http credentials', async ({context, server}) => {
|
||||
it('should work with http credentials', async ({ context, server }) => {
|
||||
server.setAuth('/empty.html', 'user', 'pass');
|
||||
|
||||
const [request, response] = await Promise.all([
|
||||
@ -376,7 +376,7 @@ it('should work with http credentials', async ({context, server}) => {
|
||||
expect(request.url).toBe('/empty.html');
|
||||
});
|
||||
|
||||
it('should work with setHTTPCredentials', async ({context, server}) => {
|
||||
it('should work with setHTTPCredentials', async ({ context, server }) => {
|
||||
server.setAuth('/empty.html', 'user', 'pass');
|
||||
const response1 = await context._request.get(server.EMPTY_PAGE);
|
||||
expect(response1.status()).toBe(401);
|
||||
@ -386,14 +386,14 @@ it('should work with setHTTPCredentials', async ({context, server}) => {
|
||||
expect(response2.status()).toBe(200);
|
||||
});
|
||||
|
||||
it('should return error with wrong credentials', async ({context, server}) => {
|
||||
it('should return error with wrong credentials', async ({ context, server }) => {
|
||||
server.setAuth('/empty.html', 'user', 'pass');
|
||||
await context.setHTTPCredentials({ username: 'user', password: 'wrong' });
|
||||
const response2 = await context._request.get(server.EMPTY_PAGE);
|
||||
expect(response2.status()).toBe(401);
|
||||
});
|
||||
|
||||
it('should support post data', async ({context, server}) => {
|
||||
it('should support post data', async ({ context, server }) => {
|
||||
const [request, response] = await Promise.all([
|
||||
server.waitForRequest('/simple.json'),
|
||||
context._request.post(`${server.PREFIX}/simple.json`, {
|
||||
@ -406,7 +406,7 @@ it('should support post data', async ({context, server}) => {
|
||||
expect(request.url).toBe('/simple.json');
|
||||
});
|
||||
|
||||
it('should add default headers', async ({context, server, page}) => {
|
||||
it('should add default headers', async ({ context, server, page }) => {
|
||||
const [request] = await Promise.all([
|
||||
server.waitForRequest('/empty.html'),
|
||||
context._request.get(server.EMPTY_PAGE)
|
||||
@ -417,7 +417,7 @@ it('should add default headers', async ({context, server, page}) => {
|
||||
expect(request.headers['accept-encoding']).toBe('gzip,deflate,br');
|
||||
});
|
||||
|
||||
it('should send content-length', async function({context, asset, server}) {
|
||||
it('should send content-length', async function({ context, asset, server }) {
|
||||
const bytes = [];
|
||||
for (let i = 0; i < 256; i++)
|
||||
bytes.push(i);
|
||||
@ -431,7 +431,7 @@ it('should send content-length', async function({context, asset, server}) {
|
||||
expect(request.headers['content-type']).toBe('application/octet-stream');
|
||||
});
|
||||
|
||||
it('should add default headers to redirects', async ({context, server, page}) => {
|
||||
it('should add default headers to redirects', async ({ context, server, page }) => {
|
||||
server.setRedirect('/redirect', '/empty.html');
|
||||
const [request] = await Promise.all([
|
||||
server.waitForRequest('/empty.html'),
|
||||
@ -443,7 +443,7 @@ it('should add default headers to redirects', async ({context, server, page}) =>
|
||||
expect(request.headers['accept-encoding']).toBe('gzip,deflate,br');
|
||||
});
|
||||
|
||||
it('should allow to override default headers', async ({context, server, page}) => {
|
||||
it('should allow to override default headers', async ({ context, server, page }) => {
|
||||
const [request] = await Promise.all([
|
||||
server.waitForRequest('/empty.html'),
|
||||
context._request.get(server.EMPTY_PAGE, {
|
||||
@ -459,21 +459,21 @@ it('should allow to override default headers', async ({context, server, page}) =
|
||||
expect(request.headers['accept-encoding']).toBe('br');
|
||||
});
|
||||
|
||||
it('should propagate custom headers with redirects', async ({context, server}) => {
|
||||
it('should propagate custom headers with redirects', async ({ context, server }) => {
|
||||
server.setRedirect('/a/redirect1', '/b/c/redirect2');
|
||||
server.setRedirect('/b/c/redirect2', '/simple.json');
|
||||
const [req1, req2, req3] = await Promise.all([
|
||||
server.waitForRequest('/a/redirect1'),
|
||||
server.waitForRequest('/b/c/redirect2'),
|
||||
server.waitForRequest('/simple.json'),
|
||||
context._request.get(`${server.PREFIX}/a/redirect1`, {headers: {'foo': 'bar'}}),
|
||||
context._request.get(`${server.PREFIX}/a/redirect1`, { headers: { 'foo': 'bar' } }),
|
||||
]);
|
||||
expect(req1.headers['foo']).toBe('bar');
|
||||
expect(req2.headers['foo']).toBe('bar');
|
||||
expect(req3.headers['foo']).toBe('bar');
|
||||
});
|
||||
|
||||
it('should propagate extra http headers with redirects', async ({context, server}) => {
|
||||
it('should propagate extra http headers with redirects', async ({ context, server }) => {
|
||||
server.setRedirect('/a/redirect1', '/b/c/redirect2');
|
||||
server.setRedirect('/b/c/redirect2', '/simple.json');
|
||||
await context.setExtraHTTPHeaders({ 'My-Secret': 'Value' });
|
||||
@ -488,7 +488,7 @@ it('should propagate extra http headers with redirects', async ({context, server
|
||||
expect(req3.headers['my-secret']).toBe('Value');
|
||||
});
|
||||
|
||||
it('should throw on invalid header value', async ({context, server}) => {
|
||||
it('should throw on invalid header value', async ({ context, server }) => {
|
||||
const error = await context._request.get(`${server.PREFIX}/a/redirect1`, {
|
||||
headers: {
|
||||
'foo': 'недопустимое значение',
|
||||
@ -497,14 +497,14 @@ it('should throw on invalid header value', async ({context, server}) => {
|
||||
expect(error.message).toContain('Invalid character in header content');
|
||||
});
|
||||
|
||||
it('should throw on non-http(s) protocol', async ({context}) => {
|
||||
it('should throw on non-http(s) protocol', async ({ context }) => {
|
||||
const error1 = await context._request.get(`data:text/plain,test`).catch(e => e);
|
||||
expect(error1.message).toContain('Protocol "data:" not supported');
|
||||
const error2 = await context._request.get(`file:///tmp/foo`).catch(e => e);
|
||||
expect(error2.message).toContain('Protocol "file:" not supported');
|
||||
});
|
||||
|
||||
it('should support https', async ({context, httpsServer}) => {
|
||||
it('should support https', async ({ context, httpsServer }) => {
|
||||
const oldValue = process.env['NODE_TLS_REJECT_UNAUTHORIZED'];
|
||||
// https://stackoverflow.com/a/21961005/552185
|
||||
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';
|
||||
@ -517,13 +517,13 @@ it('should support https', async ({context, httpsServer}) => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should support ignoreHTTPSErrors', async ({contextFactory, contextOptions, httpsServer}) => {
|
||||
it('should support ignoreHTTPSErrors', async ({ contextFactory, contextOptions, httpsServer }) => {
|
||||
const context = await contextFactory({ ...contextOptions, ignoreHTTPSErrors: true });
|
||||
const response = await context._request.get(httpsServer.EMPTY_PAGE);
|
||||
expect(response.status()).toBe(200);
|
||||
});
|
||||
|
||||
it('should resolve url relative to baseURL', async function({server, contextFactory, contextOptions}) {
|
||||
it('should resolve url relative to baseURL', async function({ server, contextFactory, contextOptions }) {
|
||||
const context = await contextFactory({
|
||||
...contextOptions,
|
||||
baseURL: server.PREFIX,
|
||||
@ -532,7 +532,7 @@ it('should resolve url relative to baseURL', async function({server, contextFact
|
||||
expect(response.url()).toBe(server.EMPTY_PAGE);
|
||||
});
|
||||
|
||||
it('should support gzip compression', async function({context, server}) {
|
||||
it('should support gzip compression', async function({ context, server }) {
|
||||
server.setRoute('/compressed', (req, res) => {
|
||||
res.writeHead(200, {
|
||||
'Content-Encoding': 'gzip',
|
||||
@ -552,7 +552,7 @@ it('should support gzip compression', async function({context, server}) {
|
||||
expect(await response.text()).toBe('Hello, world!');
|
||||
});
|
||||
|
||||
it('should throw informatibe error on corrupted gzip body', async function({context, server}) {
|
||||
it('should throw informatibe error on corrupted gzip body', async function({ context, server }) {
|
||||
server.setRoute('/corrupted', (req, res) => {
|
||||
res.writeHead(200, {
|
||||
'Content-Encoding': 'gzip',
|
||||
@ -566,7 +566,7 @@ it('should throw informatibe error on corrupted gzip body', async function({cont
|
||||
expect(error.message).toContain(`failed to decompress 'gzip' encoding`);
|
||||
});
|
||||
|
||||
it('should support brotli compression', async function({context, server}) {
|
||||
it('should support brotli compression', async function({ context, server }) {
|
||||
server.setRoute('/compressed', (req, res) => {
|
||||
res.writeHead(200, {
|
||||
'Content-Encoding': 'br',
|
||||
@ -586,7 +586,7 @@ it('should support brotli compression', async function({context, server}) {
|
||||
expect(await response.text()).toBe('Hello, world!');
|
||||
});
|
||||
|
||||
it('should throw informatibe error on corrupted brotli body', async function({context, server}) {
|
||||
it('should throw informatibe error on corrupted brotli body', async function({ context, server }) {
|
||||
server.setRoute('/corrupted', (req, res) => {
|
||||
res.writeHead(200, {
|
||||
'Content-Encoding': 'br',
|
||||
@ -600,7 +600,7 @@ it('should throw informatibe error on corrupted brotli body', async function({co
|
||||
expect(error.message).toContain(`failed to decompress 'br' encoding`);
|
||||
});
|
||||
|
||||
it('should support deflate compression', async function({context, server}) {
|
||||
it('should support deflate compression', async function({ context, server }) {
|
||||
server.setRoute('/compressed', (req, res) => {
|
||||
res.writeHead(200, {
|
||||
'Content-Encoding': 'deflate',
|
||||
@ -620,7 +620,7 @@ it('should support deflate compression', async function({context, server}) {
|
||||
expect(await response.text()).toBe('Hello, world!');
|
||||
});
|
||||
|
||||
it('should throw informatibe error on corrupted deflate body', async function({context, server}) {
|
||||
it('should throw informatibe error on corrupted deflate body', async function({ context, server }) {
|
||||
server.setRoute('/corrupted', (req, res) => {
|
||||
res.writeHead(200, {
|
||||
'Content-Encoding': 'deflate',
|
||||
@ -634,7 +634,7 @@ it('should throw informatibe error on corrupted deflate body', async function({c
|
||||
expect(error.message).toContain(`failed to decompress 'deflate' encoding`);
|
||||
});
|
||||
|
||||
it('should support timeout option', async function({context, server}) {
|
||||
it('should support timeout option', async function({ context, server }) {
|
||||
server.setRoute('/slow', (req, res) => {
|
||||
res.writeHead(200, {
|
||||
'content-length': 4096,
|
||||
@ -646,7 +646,7 @@ it('should support timeout option', async function({context, server}) {
|
||||
expect(error.message).toContain(`Request timed out after 10ms`);
|
||||
});
|
||||
|
||||
it('should support a timeout of 0', async function({context, server}) {
|
||||
it('should support a timeout of 0', async function({ context, server }) {
|
||||
server.setRoute('/slow', (req, res) => {
|
||||
res.writeHead(200, {
|
||||
'content-length': 4,
|
||||
@ -663,7 +663,7 @@ it('should support a timeout of 0', async function({context, server}) {
|
||||
expect(await response.text()).toBe('done');
|
||||
});
|
||||
|
||||
it('should respect timeout after redirects', async function({context, server}) {
|
||||
it('should respect timeout after redirects', async function({ context, server }) {
|
||||
server.setRedirect('/redirect', '/slow');
|
||||
server.setRoute('/slow', (req, res) => {
|
||||
res.writeHead(200, {
|
||||
@ -677,7 +677,7 @@ it('should respect timeout after redirects', async function({context, server}) {
|
||||
expect(error.message).toContain(`Request timed out after 100ms`);
|
||||
});
|
||||
|
||||
it('should dispose', async function({context, server}) {
|
||||
it('should dispose', async function({ context, server }) {
|
||||
const response = await context._request.get(server.PREFIX + '/simple.json');
|
||||
expect(await response.json()).toEqual({ foo: 'bar' });
|
||||
await response.dispose();
|
||||
@ -685,7 +685,7 @@ it('should dispose', async function({context, server}) {
|
||||
expect(error.message).toContain('Response has been disposed');
|
||||
});
|
||||
|
||||
it('should dispose when context closes', async function({context, server}) {
|
||||
it('should dispose when context closes', async function({ context, server }) {
|
||||
const response = await context._request.get(server.PREFIX + '/simple.json');
|
||||
expect(await response.json()).toEqual({ foo: 'bar' });
|
||||
await context.close();
|
||||
@ -693,12 +693,12 @@ it('should dispose when context closes', async function({context, server}) {
|
||||
expect(error.message).toContain('Response has been disposed');
|
||||
});
|
||||
|
||||
it('should throw on invalid first argument', async function({context}) {
|
||||
it('should throw on invalid first argument', async function({ context }) {
|
||||
const error = await context._request.get({} as any).catch(e => e);
|
||||
expect(error.message).toContain('First argument must be either URL string or Request');
|
||||
});
|
||||
|
||||
it('should override request parameters', async function({context, page, server}) {
|
||||
it('should override request parameters', async function({ context, page, server }) {
|
||||
const [pageReq] = await Promise.all([
|
||||
page.waitForRequest('**/*'),
|
||||
page.goto(server.EMPTY_PAGE)
|
||||
@ -717,7 +717,7 @@ it('should override request parameters', async function({context, page, server})
|
||||
expect((await req.postBody).toString('utf8')).toBe('data');
|
||||
});
|
||||
|
||||
it('should support application/x-www-form-urlencoded', async function({context, page, server}) {
|
||||
it('should support application/x-www-form-urlencoded', async function({ context, page, server }) {
|
||||
const [req] = await Promise.all([
|
||||
server.waitForRequest('/empty.html'),
|
||||
context._request.post(server.EMPTY_PAGE, {
|
||||
@ -741,7 +741,7 @@ it('should support application/x-www-form-urlencoded', async function({context,
|
||||
expect(params.get('file')).toBe('f.js');
|
||||
});
|
||||
|
||||
it('should encode to application/json by default', async function({context, page, server}) {
|
||||
it('should encode to application/json by default', async function({ context, page, server }) {
|
||||
const data = {
|
||||
firstName: 'John',
|
||||
lastName: 'Doe',
|
||||
@ -760,13 +760,13 @@ it('should encode to application/json by default', async function({context, page
|
||||
expect(json).toEqual(data);
|
||||
});
|
||||
|
||||
it('should support multipart/form-data', async function({context, page, server}) {
|
||||
it('should support multipart/form-data', async function({ context, page, server }) {
|
||||
const formReceived = new Promise<any>(resolve => {
|
||||
server.setRoute('/empty.html', async (serverRequest, res) => {
|
||||
const form = new formidable.IncomingForm();
|
||||
form.parse(serverRequest, (error, fields, files) => {
|
||||
server.serveFile(serverRequest, res);
|
||||
resolve({error, fields, files, serverRequest });
|
||||
resolve({ error, fields, files, serverRequest });
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -776,7 +776,7 @@ it('should support multipart/form-data', async function({context, page, server})
|
||||
mimeType: 'text/javascript',
|
||||
buffer: Buffer.from('var x = 10;\r\n;console.log(x);')
|
||||
};
|
||||
const [{error, fields, files, serverRequest}, response] = await Promise.all([
|
||||
const [{ error, fields, files, serverRequest }, response] = await Promise.all([
|
||||
formReceived,
|
||||
context._request.post(server.EMPTY_PAGE, {
|
||||
headers: {
|
||||
@ -800,18 +800,18 @@ it('should support multipart/form-data', async function({context, page, server})
|
||||
expect(response.status()).toBe(200);
|
||||
});
|
||||
|
||||
it('should support multipart/form-data with ReadSream values', async function({context, page, asset, server}) {
|
||||
it('should support multipart/form-data with ReadSream values', async function({ context, page, asset, server }) {
|
||||
const formReceived = new Promise<any>(resolve => {
|
||||
server.setRoute('/empty.html', async (serverRequest, res) => {
|
||||
const form = new formidable.IncomingForm();
|
||||
form.parse(serverRequest, (error, fields, files) => {
|
||||
server.serveFile(serverRequest, res);
|
||||
resolve({error, fields, files, serverRequest });
|
||||
resolve({ error, fields, files, serverRequest });
|
||||
});
|
||||
});
|
||||
});
|
||||
const readStream = fs.createReadStream(asset('simplezip.json'));
|
||||
const [{error, fields, files, serverRequest}, response] = await Promise.all([
|
||||
const [{ error, fields, files, serverRequest }, response] = await Promise.all([
|
||||
formReceived,
|
||||
context._request.post(server.EMPTY_PAGE, {
|
||||
headers: {
|
||||
@ -836,7 +836,7 @@ it('should support multipart/form-data with ReadSream values', async function({c
|
||||
expect(response.status()).toBe(200);
|
||||
});
|
||||
|
||||
it('should throw nice error on unsupported encoding', async function({context, server}) {
|
||||
it('should throw nice error on unsupported encoding', async function({ context, server }) {
|
||||
const error = await context._request.post(server.EMPTY_PAGE, {
|
||||
headers: {
|
||||
'content-type': 'unknown'
|
||||
@ -849,7 +849,7 @@ it('should throw nice error on unsupported encoding', async function({context, s
|
||||
expect(error.message).toContain('Cannot serialize data using content type: unknown');
|
||||
});
|
||||
|
||||
it('should throw nice error on unsupported data type', async function({context, server}) {
|
||||
it('should throw nice error on unsupported data type', async function({ context, server }) {
|
||||
const error = await context._request.post(server.EMPTY_PAGE, {
|
||||
headers: {
|
||||
'content-type': 'application/json'
|
||||
@ -859,7 +859,7 @@ it('should throw nice error on unsupported data type', async function({context,
|
||||
expect(error.message).toContain(`Unexpected 'data' type`);
|
||||
});
|
||||
|
||||
it('should throw when data passed for unsupported request', async function({context, server}) {
|
||||
it('should throw when data passed for unsupported request', async function({ context, server }) {
|
||||
const error = await context._request.fetch(server.EMPTY_PAGE, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import { browserTest as it, expect } from './config/browserTest';
|
||||
|
||||
it('should affect accept-language header', async ({browser, server}) => {
|
||||
it('should affect accept-language header', async ({ browser, server }) => {
|
||||
const context = await browser.newContext({ locale: 'fr-CH' });
|
||||
const page = await context.newPage();
|
||||
const [request] = await Promise.all([
|
||||
@ -28,14 +28,14 @@ it('should affect accept-language header', async ({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should affect navigator.language', async ({browser, server}) => {
|
||||
it('should affect navigator.language', async ({ browser, server }) => {
|
||||
const context = await browser.newContext({ locale: 'fr-CH' });
|
||||
const page = await context.newPage();
|
||||
expect(await page.evaluate(() => navigator.language)).toBe('fr-CH');
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should format number', async ({browser, server}) => {
|
||||
it('should format number', async ({ browser, server }) => {
|
||||
{
|
||||
const context = await browser.newContext({ locale: 'en-US' });
|
||||
const page = await context.newPage();
|
||||
@ -52,7 +52,7 @@ it('should format number', async ({browser, server}) => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should format date', async ({browser, server, browserName}) => {
|
||||
it('should format date', async ({ browser, server, browserName }) => {
|
||||
{
|
||||
const context = await browser.newContext({ locale: 'en-US', timezoneId: 'America/Los_Angeles' });
|
||||
const page = await context.newPage();
|
||||
@ -71,7 +71,7 @@ it('should format date', async ({browser, server, browserName}) => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should format number in popups', async ({browser, server}) => {
|
||||
it('should format number in popups', async ({ browser, server }) => {
|
||||
const context = await browser.newContext({ locale: 'fr-CH' });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -86,7 +86,7 @@ it('should format number in popups', async ({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should affect navigator.language in popups', async ({browser, server}) => {
|
||||
it('should affect navigator.language in popups', async ({ browser, server }) => {
|
||||
const context = await browser.newContext({ locale: 'fr-CH' });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -100,7 +100,7 @@ it('should affect navigator.language in popups', async ({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should work for multiple pages sharing same process', async ({browser, server}) => {
|
||||
it('should work for multiple pages sharing same process', async ({ browser, server }) => {
|
||||
const context = await browser.newContext({ locale: 'ru-RU' });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -115,7 +115,7 @@ it('should work for multiple pages sharing same process', async ({browser, serve
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should be isolated between contexts', async ({browser, server}) => {
|
||||
it('should be isolated between contexts', async ({ browser, server }) => {
|
||||
const context1 = await browser.newContext({ locale: 'en-US' });
|
||||
const promises = [];
|
||||
// By default firefox limits number of child web processes to 8.
|
||||
@ -138,7 +138,7 @@ it('should be isolated between contexts', async ({browser, server}) => {
|
||||
]);
|
||||
});
|
||||
|
||||
it('should not change default locale in another context', async ({browser, server}) => {
|
||||
it('should not change default locale in another context', async ({ browser, server }) => {
|
||||
async function getContextLocale(context) {
|
||||
const page = await context.newPage();
|
||||
return await page.evaluate(() => (new Intl.NumberFormat()).resolvedOptions().locale);
|
||||
@ -152,7 +152,7 @@ it('should not change default locale in another context', async ({browser, serve
|
||||
}
|
||||
const localeOverride = defaultLocale === 'ru-RU' ? 'de-DE' : 'ru-RU';
|
||||
{
|
||||
const context = await browser.newContext({ locale: localeOverride});
|
||||
const context = await browser.newContext({ locale: localeOverride });
|
||||
expect(await getContextLocale(context)).toBe(localeOverride);
|
||||
await context.close();
|
||||
}
|
||||
@ -163,13 +163,13 @@ it('should not change default locale in another context', async ({browser, serve
|
||||
}
|
||||
});
|
||||
|
||||
it('should format number in workers', async ({browser, server}) => {
|
||||
it('should format number in workers', async ({ browser, server }) => {
|
||||
const context = await browser.newContext({ locale: 'ru-RU' });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const [worker] = await Promise.all([
|
||||
page.waitForEvent('worker'),
|
||||
page.evaluate(() => new Worker(URL.createObjectURL(new Blob(['console.log(1)'], {type: 'application/javascript'})))),
|
||||
page.evaluate(() => new Worker(URL.createObjectURL(new Blob(['console.log(1)'], { type: 'application/javascript' })))),
|
||||
]);
|
||||
expect(await worker.evaluate(() => (10000.20).toLocaleString())).toBe('10\u00A0000,2');
|
||||
await context.close();
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import { browserTest as it, expect } from './config/browserTest';
|
||||
|
||||
it('BrowserContext.Events.Request', async ({context, server}) => {
|
||||
it('BrowserContext.Events.Request', async ({ context, server }) => {
|
||||
const page = await context.newPage();
|
||||
const requests = [];
|
||||
context.on('request', request => requests.push(request));
|
||||
@ -36,7 +36,7 @@ it('BrowserContext.Events.Request', async ({context, server}) => {
|
||||
]);
|
||||
});
|
||||
|
||||
it('BrowserContext.Events.Response', async ({context, server}) => {
|
||||
it('BrowserContext.Events.Response', async ({ context, server }) => {
|
||||
const page = await context.newPage();
|
||||
const responses = [];
|
||||
context.on('response', response => responses.push(response));
|
||||
@ -55,7 +55,7 @@ it('BrowserContext.Events.Response', async ({context, server}) => {
|
||||
]);
|
||||
});
|
||||
|
||||
it('BrowserContext.Events.RequestFailed', async ({context, server}) => {
|
||||
it('BrowserContext.Events.RequestFailed', async ({ context, server }) => {
|
||||
server.setRoute('/one-style.css', (_, res) => {
|
||||
res.setHeader('Content-Type', 'text/css');
|
||||
res.connection.destroy();
|
||||
@ -72,7 +72,7 @@ it('BrowserContext.Events.RequestFailed', async ({context, server}) => {
|
||||
});
|
||||
|
||||
|
||||
it('BrowserContext.Events.RequestFinished', async ({context, server}) => {
|
||||
it('BrowserContext.Events.RequestFinished', async ({ context, server }) => {
|
||||
const page = await context.newPage();
|
||||
const [response] = await Promise.all([
|
||||
page.goto(server.EMPTY_PAGE),
|
||||
@ -86,7 +86,7 @@ it('BrowserContext.Events.RequestFinished', async ({context, server}) => {
|
||||
expect(request.failure()).toBe(null);
|
||||
});
|
||||
|
||||
it('should fire events in proper order', async ({context, server}) => {
|
||||
it('should fire events in proper order', async ({ context, server }) => {
|
||||
const page = await context.newPage();
|
||||
const events = [];
|
||||
context.on('request', () => events.push('request'));
|
||||
@ -103,7 +103,7 @@ it('should fire events in proper order', async ({context, server}) => {
|
||||
]);
|
||||
});
|
||||
|
||||
it('should not fire events for favicon or favicon redirects', async ({context, page, server, browserName, channel, headless}) => {
|
||||
it('should not fire events for favicon or favicon redirects', async ({ context, page, server, browserName, channel, headless }) => {
|
||||
it.skip(headless && browserName !== 'firefox', 'headless browsers, except firefox, do not request favicons');
|
||||
it.skip(!headless && browserName === 'webkit' && !channel, 'headed webkit does not have a favicon feature');
|
||||
const favicon = `/no-cache/favicon.ico`;
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import { browserTest as it, expect } from './config/browserTest';
|
||||
|
||||
it('should have url', async ({browser, server}) => {
|
||||
it('should have url', async ({ browser, server }) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
const [otherPage] = await Promise.all([
|
||||
@ -28,7 +28,7 @@ it('should have url', async ({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should have url after domcontentloaded', async ({browser, server}) => {
|
||||
it('should have url after domcontentloaded', async ({ browser, server }) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
const [otherPage] = await Promise.all([
|
||||
@ -40,7 +40,7 @@ it('should have url after domcontentloaded', async ({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should have about:blank url with domcontentloaded', async ({browser, server}) => {
|
||||
it('should have about:blank url with domcontentloaded', async ({ browser, server }) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
const [otherPage] = await Promise.all([
|
||||
@ -52,7 +52,7 @@ it('should have about:blank url with domcontentloaded', async ({browser, server}
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should have about:blank for empty url with domcontentloaded', async ({browser, server}) => {
|
||||
it('should have about:blank for empty url with domcontentloaded', async ({ browser, server }) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
const [otherPage] = await Promise.all([
|
||||
@ -64,7 +64,7 @@ it('should have about:blank for empty url with domcontentloaded', async ({browse
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should report when a new page is created and closed', async ({browser, server}) => {
|
||||
it('should report when a new page is created and closed', async ({ browser, server }) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
const [otherPage] = await Promise.all([
|
||||
@ -91,7 +91,7 @@ it('should report when a new page is created and closed', async ({browser, serve
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should report initialized pages', async ({browser, server}) => {
|
||||
it('should report initialized pages', async ({ browser, server }) => {
|
||||
const context = await browser.newContext();
|
||||
const pagePromise = context.waitForEvent('page');
|
||||
context.newPage();
|
||||
@ -106,7 +106,7 @@ it('should report initialized pages', async ({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should not crash while redirecting of original request was missed', async ({browser, server}) => {
|
||||
it('should not crash while redirecting of original request was missed', async ({ browser, server }) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
let serverResponse = null;
|
||||
@ -126,7 +126,7 @@ it('should not crash while redirecting of original request was missed', async ({
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should have an opener', async ({browser, server}) => {
|
||||
it('should have an opener', async ({ browser, server }) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -140,7 +140,7 @@ it('should have an opener', async ({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should fire page lifecycle events', async function({browser, server}) {
|
||||
it('should fire page lifecycle events', async function({ browser, server }) {
|
||||
const context = await browser.newContext();
|
||||
const events = [];
|
||||
context.on('page', async page => {
|
||||
@ -157,7 +157,7 @@ it('should fire page lifecycle events', async function({browser, server}) {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should work with Shift-clicking', async ({browser, server, browserName}) => {
|
||||
it('should work with Shift-clicking', async ({ browser, server, browserName }) => {
|
||||
it.fixme(browserName === 'webkit', 'WebKit: Shift+Click does not open a new window.');
|
||||
|
||||
const context = await browser.newContext();
|
||||
@ -172,7 +172,7 @@ it('should work with Shift-clicking', async ({browser, server, browserName}) =>
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should work with Ctrl-clicking', async ({browser, server, isMac, browserName}) => {
|
||||
it('should work with Ctrl-clicking', async ({ browser, server, isMac, browserName }) => {
|
||||
it.fixme(browserName === 'webkit', 'Ctrl+Click does not open a new tab.');
|
||||
it.fixme(browserName === 'firefox', 'Reports an opener in this case.');
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
import { browserTest as it, expect } from './config/browserTest';
|
||||
import { attachFrame, chromiumVersionLessThan } from './config/utils';
|
||||
|
||||
it('should not be visible in context.pages', async ({contextFactory}) => {
|
||||
it('should not be visible in context.pages', async ({ contextFactory }) => {
|
||||
const context = await contextFactory();
|
||||
const page = await context.newPage();
|
||||
expect(context.pages()).toContain(page);
|
||||
@ -26,7 +26,7 @@ it('should not be visible in context.pages', async ({contextFactory}) => {
|
||||
expect(context.pages()).not.toContain(page);
|
||||
});
|
||||
|
||||
it('page.context should return the correct instance', async function({contextFactory}) {
|
||||
it('page.context should return the correct instance', async function({ contextFactory }) {
|
||||
const context = await contextFactory();
|
||||
const page = await context.newPage();
|
||||
expect(page.context()).toBe(context);
|
||||
@ -43,7 +43,7 @@ it('frame.focus should work multiple times', async ({ contextFactory }) => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should click with disabled javascript', async ({browser, server}) => {
|
||||
it('should click with disabled javascript', async ({ browser, server }) => {
|
||||
const context = await browser.newContext({ javaScriptEnabled: false });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.PREFIX + '/wrappedlink.html');
|
||||
@ -55,7 +55,7 @@ it('should click with disabled javascript', async ({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should not hang with touch-enabled viewports', async ({browser, playwright}) => {
|
||||
it('should not hang with touch-enabled viewports', async ({ browser, playwright }) => {
|
||||
// @see https://github.com/GoogleChrome/puppeteer/issues/161
|
||||
const { viewport, hasTouch } = playwright.devices['iPhone 6'];
|
||||
const context = await browser.newContext({ viewport, hasTouch });
|
||||
@ -66,7 +66,7 @@ it('should not hang with touch-enabled viewports', async ({browser, playwright})
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should click the button with deviceScaleFactor set', async ({browser, server}) => {
|
||||
it('should click the button with deviceScaleFactor set', async ({ browser, server }) => {
|
||||
const context = await browser.newContext({ viewport: { width: 400, height: 400 }, deviceScaleFactor: 5 });
|
||||
const page = await context.newPage();
|
||||
expect(await page.evaluate(() => window.devicePixelRatio)).toBe(5);
|
||||
@ -79,7 +79,7 @@ it('should click the button with deviceScaleFactor set', async ({browser, server
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should click the button with offset with page scale', async ({browser, server, headless, browserName, browserVersion}) => {
|
||||
it('should click the button with offset with page scale', async ({ browser, server, headless, browserName, browserVersion }) => {
|
||||
it.skip(browserName === 'firefox');
|
||||
|
||||
const context = await browser.newContext({ viewport: { width: 400, height: 400 }, isMobile: true });
|
||||
@ -131,7 +131,7 @@ it('should return bounding box with page scale', async ({ browser, server, brows
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should not leak listeners during navigation of 20 pages', async ({contextFactory, server}) => {
|
||||
it('should not leak listeners during navigation of 20 pages', async ({ contextFactory, server }) => {
|
||||
it.slow(true, 'We open 20 pages here!');
|
||||
|
||||
const context = await contextFactory();
|
||||
|
@ -40,7 +40,7 @@ it('should throw for missing global proxy on Chromium Windows', async ({ browser
|
||||
}
|
||||
});
|
||||
|
||||
it('should work when passing the proxy only on the context level', async ({browserName, platform, browserType, browserOptions, contextOptions, server, proxyServer}) => {
|
||||
it('should work when passing the proxy only on the context level', async ({ browserName, platform, browserType, browserOptions, contextOptions, server, proxyServer }) => {
|
||||
// Currently an upstream bug in the network stack of Chromium which leads that
|
||||
// the wrong proxy gets used in the BrowserContext.
|
||||
it.fixme(browserName === 'chromium' && platform === 'win32');
|
||||
@ -100,7 +100,7 @@ it('should use proxy twice', async ({ contextFactory, server, proxyServer }) =>
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should use proxy for second page', async ({contextFactory, server, proxyServer}) => {
|
||||
it('should use proxy for second page', async ({ contextFactory, server, proxyServer }) => {
|
||||
proxyServer.forwardTo(server.PORT);
|
||||
const context = await contextFactory({
|
||||
proxy: { server: `localhost:${proxyServer.PORT}` }
|
||||
@ -136,7 +136,7 @@ it('should use proxy for https urls', async ({ contextFactory, server, httpsServ
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should work with IP:PORT notion', async ({contextFactory, server, proxyServer}) => {
|
||||
it('should work with IP:PORT notion', async ({ contextFactory, server, proxyServer }) => {
|
||||
proxyServer.forwardTo(server.PORT);
|
||||
const context = await contextFactory({
|
||||
proxy: { server: `127.0.0.1:${proxyServer.PORT}` }
|
||||
@ -148,21 +148,21 @@ it('should work with IP:PORT notion', async ({contextFactory, server, proxyServe
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should throw for socks5 authentication', async ({contextFactory}) => {
|
||||
it('should throw for socks5 authentication', async ({ contextFactory }) => {
|
||||
const error = await contextFactory({
|
||||
proxy: { server: `socks5://localhost:1234`, username: 'user', password: 'secret' }
|
||||
}).catch(e => e);
|
||||
expect(error.message).toContain('Browser does not support socks5 proxy authentication');
|
||||
});
|
||||
|
||||
it('should throw for socks4 authentication', async ({contextFactory}) => {
|
||||
it('should throw for socks4 authentication', async ({ contextFactory }) => {
|
||||
const error = await contextFactory({
|
||||
proxy: { server: `socks4://localhost:1234`, username: 'user', password: 'secret' }
|
||||
}).catch(e => e);
|
||||
expect(error.message).toContain('Socks4 proxy protocol does not support authentication');
|
||||
});
|
||||
|
||||
it('should authenticate', async ({contextFactory, server, proxyServer}) => {
|
||||
it('should authenticate', async ({ contextFactory, server, proxyServer }) => {
|
||||
proxyServer.forwardTo(server.PORT);
|
||||
let auth;
|
||||
proxyServer.setAuthHandler(req => {
|
||||
@ -180,7 +180,7 @@ it('should authenticate', async ({contextFactory, server, proxyServer}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should authenticate with empty password', async ({contextFactory, server, proxyServer}) => {
|
||||
it('should authenticate with empty password', async ({ contextFactory, server, proxyServer }) => {
|
||||
proxyServer.forwardTo(server.PORT);
|
||||
let auth;
|
||||
proxyServer.setAuthHandler(req => {
|
||||
@ -197,7 +197,7 @@ it('should authenticate with empty password', async ({contextFactory, server, pr
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should isolate proxy credentials between contexts', async ({contextFactory, server, browserName, proxyServer}) => {
|
||||
it('should isolate proxy credentials between contexts', async ({ contextFactory, server, browserName, proxyServer }) => {
|
||||
it.fixme(browserName === 'firefox', 'Credentials from the first context stick around');
|
||||
|
||||
proxyServer.forwardTo(server.PORT);
|
||||
@ -229,7 +229,7 @@ it('should isolate proxy credentials between contexts', async ({contextFactory,
|
||||
}
|
||||
});
|
||||
|
||||
it('should exclude patterns', async ({contextFactory, server, browserName, headless, proxyServer}) => {
|
||||
it('should exclude patterns', async ({ contextFactory, server, browserName, headless, proxyServer }) => {
|
||||
it.fixme(browserName === 'chromium' && !headless, 'Chromium headed crashes with CHECK(!in_frame_tree_) in RenderFrameImpl::OnDeleteFrame.');
|
||||
|
||||
proxyServer.forwardTo(server.PORT);
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import { browserTest as it, expect } from './config/browserTest';
|
||||
|
||||
it('should intercept', async ({browser, server}) => {
|
||||
it('should intercept', async ({ browser, server }) => {
|
||||
const context = await browser.newContext();
|
||||
let intercepted = false;
|
||||
await context.route('**/empty.html', route => {
|
||||
@ -40,7 +40,7 @@ it('should intercept', async ({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should unroute', async ({browser, server}) => {
|
||||
it('should unroute', async ({ browser, server }) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
|
||||
@ -78,7 +78,7 @@ it('should unroute', async ({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should yield to page.route', async ({browser, server}) => {
|
||||
it('should yield to page.route', async ({ browser, server }) => {
|
||||
const context = await browser.newContext();
|
||||
await context.route('**/empty.html', route => {
|
||||
route.fulfill({ status: 200, body: 'context' });
|
||||
@ -93,7 +93,7 @@ it('should yield to page.route', async ({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should fall back to context.route', async ({browser, server}) => {
|
||||
it('should fall back to context.route', async ({ browser, server }) => {
|
||||
const context = await browser.newContext();
|
||||
await context.route('**/empty.html', route => {
|
||||
route.fulfill({ status: 200, body: 'context' });
|
||||
@ -108,7 +108,7 @@ it('should fall back to context.route', async ({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should support Set-Cookie header', async ({contextFactory, server, browserName}) => {
|
||||
it('should support Set-Cookie header', async ({ contextFactory, server, browserName }) => {
|
||||
it.fixme(browserName === 'webkit');
|
||||
|
||||
const context = await contextFactory();
|
||||
@ -135,7 +135,7 @@ it('should support Set-Cookie header', async ({contextFactory, server, browserNa
|
||||
}]);
|
||||
});
|
||||
|
||||
it('should ignore secure Set-Cookie header for insecure requests', async ({contextFactory, server, browserName}) => {
|
||||
it('should ignore secure Set-Cookie header for insecure requests', async ({ contextFactory, server, browserName }) => {
|
||||
it.fixme(browserName === 'webkit');
|
||||
|
||||
const context = await contextFactory();
|
||||
@ -153,7 +153,7 @@ it('should ignore secure Set-Cookie header for insecure requests', async ({conte
|
||||
expect(await context.cookies()).toEqual([]);
|
||||
});
|
||||
|
||||
it('should use Set-Cookie header in future requests', async ({contextFactory, server, browserName}) => {
|
||||
it('should use Set-Cookie header in future requests', async ({ contextFactory, server, browserName }) => {
|
||||
it.fixme(browserName === 'webkit');
|
||||
|
||||
const context = await contextFactory();
|
||||
@ -189,7 +189,7 @@ it('should use Set-Cookie header in future requests', async ({contextFactory, se
|
||||
expect(cookie).toBe('name=value');
|
||||
});
|
||||
|
||||
it('should work with ignoreHTTPSErrors', async ({browser, httpsServer}) => {
|
||||
it('should work with ignoreHTTPSErrors', async ({ browser, httpsServer }) => {
|
||||
const context = await browser.newContext({ ignoreHTTPSErrors: true });
|
||||
const page = await context.newPage();
|
||||
|
||||
@ -199,12 +199,12 @@ it('should work with ignoreHTTPSErrors', async ({browser, httpsServer}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should support the times parameter with route matching', async ({context, page, server}) => {
|
||||
it('should support the times parameter with route matching', async ({ context, page, server }) => {
|
||||
const intercepted = [];
|
||||
await context.route('**/empty.html', route => {
|
||||
intercepted.push(1);
|
||||
route.continue();
|
||||
}, { times: 1});
|
||||
}, { times: 1 });
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import { browserTest as it, expect } from './config/browserTest';
|
||||
|
||||
it('should override extra headers from browser context', async ({browser, server}) => {
|
||||
it('should override extra headers from browser context', async ({ browser, server }) => {
|
||||
const context = await browser.newContext({
|
||||
extraHTTPHeaders: { 'fOo': 'bAr', 'baR': 'foO' },
|
||||
});
|
||||
@ -34,7 +34,7 @@ it('should override extra headers from browser context', async ({browser, server
|
||||
expect(request.headers['bar']).toBe('foO');
|
||||
});
|
||||
|
||||
it('should throw for non-string header values', async ({browser}) => {
|
||||
it('should throw for non-string header values', async ({ browser }) => {
|
||||
const error3 = await browser.newContext({ extraHTTPHeaders: { 'foo': null } }).catch(e => e);
|
||||
expect(error3.message).toContain('Expected value of header "foo" to be String, but "object" is found.');
|
||||
});
|
||||
|
@ -45,7 +45,7 @@ it('should work', async ({ browser, browserName }) => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should throw for invalid timezone IDs when creating pages', async ({browser}) => {
|
||||
it('should throw for invalid timezone IDs when creating pages', async ({ browser }) => {
|
||||
for (const timezoneId of ['Foo/Bar', 'Baz/Qux']) {
|
||||
let error = null;
|
||||
const context = await browser.newContext({ timezoneId });
|
||||
@ -55,7 +55,7 @@ it('should throw for invalid timezone IDs when creating pages', async ({browser}
|
||||
}
|
||||
});
|
||||
|
||||
it('should work for multiple pages sharing same process', async ({browser, server}) => {
|
||||
it('should work for multiple pages sharing same process', async ({ browser, server }) => {
|
||||
const context = await browser.newContext({ timezoneId: 'Europe/Moscow' });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -70,7 +70,7 @@ it('should work for multiple pages sharing same process', async ({browser, serve
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should not change default timezone in another context', async ({browser, server}) => {
|
||||
it('should not change default timezone in another context', async ({ browser, server }) => {
|
||||
async function getContextTimezone(context) {
|
||||
const page = await context.newPage();
|
||||
return await page.evaluate(() => Intl.DateTimeFormat().resolvedOptions().timeZone);
|
||||
@ -84,7 +84,7 @@ it('should not change default timezone in another context', async ({browser, ser
|
||||
}
|
||||
const timezoneOverride = defaultTimezone === 'Europe/Moscow' ? 'America/Los_Angeles' : 'Europe/Moscow';
|
||||
{
|
||||
const context = await browser.newContext({ timezoneId: timezoneOverride});
|
||||
const context = await browser.newContext({ timezoneId: timezoneOverride });
|
||||
expect(await getContextTimezone(context)).toBe(timezoneOverride);
|
||||
await context.close();
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
import { browserTest as it, expect } from './config/browserTest';
|
||||
import { attachFrame } from './config/utils';
|
||||
|
||||
it('should work', async ({browser, server}) => {
|
||||
it('should work', async ({ browser, server }) => {
|
||||
{
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
@ -37,7 +37,7 @@ it('should work', async ({browser, server}) => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should work for subframes', async ({browser, server}) => {
|
||||
it('should work for subframes', async ({ browser, server }) => {
|
||||
{
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
@ -56,7 +56,7 @@ it('should work for subframes', async ({browser, server}) => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should emulate device user-agent', async ({browser, server, playwright}) => {
|
||||
it('should emulate device user-agent', async ({ browser, server, playwright }) => {
|
||||
{
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
@ -73,7 +73,7 @@ it('should emulate device user-agent', async ({browser, server, playwright}) =>
|
||||
}
|
||||
});
|
||||
|
||||
it('should make a copy of default options', async ({browser, server}) => {
|
||||
it('should make a copy of default options', async ({ browser, server }) => {
|
||||
const options = { userAgent: 'foobar' };
|
||||
const context = await browser.newContext(options);
|
||||
options.userAgent = 'wrong';
|
||||
|
@ -20,18 +20,18 @@ import { browserTest as it, expect } from './config/browserTest';
|
||||
it.describe('mobile viewport', () => {
|
||||
it.skip(({ browserName }) => browserName === 'firefox');
|
||||
|
||||
it('should support mobile emulation', async ({playwright, browser, server}) => {
|
||||
it('should support mobile emulation', async ({ playwright, browser, server }) => {
|
||||
const iPhone = playwright.devices['iPhone 6'];
|
||||
const context = await browser.newContext({ ...iPhone });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.PREFIX + '/mobile.html');
|
||||
expect(await page.evaluate(() => window.innerWidth)).toBe(375);
|
||||
await page.setViewportSize({width: 400, height: 300});
|
||||
await page.setViewportSize({ width: 400, height: 300 });
|
||||
expect(await page.evaluate(() => window.innerWidth)).toBe(400);
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should support touch emulation', async ({playwright, browser, server}) => {
|
||||
it('should support touch emulation', async ({ playwright, browser, server }) => {
|
||||
const iPhone = playwright.devices['iPhone 6'];
|
||||
const context = await browser.newContext({ ...iPhone });
|
||||
const page = await context.newPage();
|
||||
@ -54,7 +54,7 @@ it.describe('mobile viewport', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should be detectable by Modernizr', async ({playwright, browser, server}) => {
|
||||
it('should be detectable by Modernizr', async ({ playwright, browser, server }) => {
|
||||
const iPhone = playwright.devices['iPhone 6'];
|
||||
const context = await browser.newContext({ ...iPhone });
|
||||
const page = await context.newPage();
|
||||
@ -63,16 +63,16 @@ it.describe('mobile viewport', () => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should detect touch when applying viewport with touches', async ({browser, server}) => {
|
||||
it('should detect touch when applying viewport with touches', async ({ browser, server }) => {
|
||||
const context = await browser.newContext({ viewport: { width: 800, height: 600 }, hasTouch: true });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.addScriptTag({url: server.PREFIX + '/modernizr.js'});
|
||||
await page.addScriptTag({ url: server.PREFIX + '/modernizr.js' });
|
||||
expect(await page.evaluate(() => window['Modernizr'].touchevents)).toBe(true);
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should support landscape emulation', async ({playwright, browser, server}) => {
|
||||
it('should support landscape emulation', async ({ playwright, browser, server }) => {
|
||||
const iPhone = playwright.devices['iPhone 6'];
|
||||
const iPhoneLandscape = playwright.devices['iPhone 6 landscape'];
|
||||
const context1 = await browser.newContext({ ...iPhone });
|
||||
@ -86,17 +86,17 @@ it.describe('mobile viewport', () => {
|
||||
await context2.close();
|
||||
});
|
||||
|
||||
it('should support window.orientation emulation', async ({browser, server}) => {
|
||||
it('should support window.orientation emulation', async ({ browser, server }) => {
|
||||
const context = await browser.newContext({ viewport: { width: 300, height: 400 }, isMobile: true });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.PREFIX + '/mobile.html');
|
||||
expect(await page.evaluate(() => window.orientation)).toBe(0);
|
||||
await page.setViewportSize({width: 400, height: 300});
|
||||
await page.setViewportSize({ width: 400, height: 300 });
|
||||
expect(await page.evaluate(() => window.orientation)).toBe(90);
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should fire orientationchange event', async ({browser, server}) => {
|
||||
it('should fire orientationchange event', async ({ browser, server }) => {
|
||||
const context = await browser.newContext({ viewport: { width: 300, height: 400 }, isMobile: true });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.PREFIX + '/mobile.html');
|
||||
@ -106,32 +106,32 @@ it.describe('mobile viewport', () => {
|
||||
});
|
||||
|
||||
const event1 = page.waitForEvent('console');
|
||||
await page.setViewportSize({width: 400, height: 300});
|
||||
await page.setViewportSize({ width: 400, height: 300 });
|
||||
expect((await event1).text()).toBe('1');
|
||||
|
||||
const event2 = page.waitForEvent('console');
|
||||
await page.setViewportSize({width: 300, height: 400});
|
||||
await page.setViewportSize({ width: 300, height: 400 });
|
||||
expect((await event2).text()).toBe('2');
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('default mobile viewports to 980 width', async ({browser, server}) => {
|
||||
const context = await browser.newContext({ viewport: {width: 320, height: 480 }, isMobile: true });
|
||||
it('default mobile viewports to 980 width', async ({ browser, server }) => {
|
||||
const context = await browser.newContext({ viewport: { width: 320, height: 480 }, isMobile: true });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.PREFIX + '/empty.html');
|
||||
expect(await page.evaluate(() => window.innerWidth)).toBe(980);
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('respect meta viewport tag', async ({browser, server}) => {
|
||||
const context = await browser.newContext({ viewport: {width: 320, height: 480 }, isMobile: true });
|
||||
it('respect meta viewport tag', async ({ browser, server }) => {
|
||||
const context = await browser.newContext({ viewport: { width: 320, height: 480 }, isMobile: true });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.PREFIX + '/mobile.html');
|
||||
expect(await page.evaluate(() => window.innerWidth)).toBe(320);
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should emulate the hover media feature', async ({playwright, browser}) => {
|
||||
it('should emulate the hover media feature', async ({ playwright, browser }) => {
|
||||
const iPhone = playwright.devices['iPhone 6'];
|
||||
const mobilepage = await browser.newPage({ ...iPhone });
|
||||
expect(await mobilepage.evaluate(() => matchMedia('(hover: hover)').matches)).toBe(false);
|
||||
@ -156,21 +156,21 @@ it.describe('mobile viewport', () => {
|
||||
await desktopPage.close();
|
||||
});
|
||||
|
||||
it('mouse should work with mobile viewports and cross process navigations', async ({browser, server, browserName}) => {
|
||||
it('mouse should work with mobile viewports and cross process navigations', async ({ browser, server, browserName }) => {
|
||||
// @see https://crbug.com/929806
|
||||
const context = await browser.newContext({ viewport: {width: 360, height: 640}, isMobile: true });
|
||||
const context = await browser.newContext({ viewport: { width: 360, height: 640 }, isMobile: true });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.goto(server.CROSS_PROCESS_PREFIX + '/mobile.html');
|
||||
await page.evaluate(() => {
|
||||
document.addEventListener('click', event => {
|
||||
window['result'] = {x: event.clientX, y: event.clientY};
|
||||
window['result'] = { x: event.clientX, y: event.clientY };
|
||||
});
|
||||
});
|
||||
|
||||
await page.mouse.click(30, 40);
|
||||
|
||||
expect(await page.evaluate('result')).toEqual({x: 30, y: 40});
|
||||
expect(await page.evaluate('result')).toEqual({ x: 30, y: 40 });
|
||||
await context.close();
|
||||
});
|
||||
});
|
||||
|
@ -19,17 +19,17 @@ import { contextTest as it, expect } from './config/browserTest';
|
||||
import { browserTest } from './config/browserTest';
|
||||
import { verifyViewport } from './config/utils';
|
||||
|
||||
it('should get the proper default viewport size', async ({page, server}) => {
|
||||
it('should get the proper default viewport size', async ({ page, server }) => {
|
||||
await verifyViewport(page, 1280, 720);
|
||||
});
|
||||
|
||||
it('should set the proper viewport size', async ({page, server}) => {
|
||||
it('should set the proper viewport size', async ({ page, server }) => {
|
||||
await verifyViewport(page, 1280, 720);
|
||||
await page.setViewportSize({width: 123, height: 456});
|
||||
await page.setViewportSize({ width: 123, height: 456 });
|
||||
await verifyViewport(page, 123, 456);
|
||||
});
|
||||
|
||||
it('should return correct outerWidth and outerHeight', async ({page}) => {
|
||||
it('should return correct outerWidth and outerHeight', async ({ page }) => {
|
||||
const size = await page.evaluate(() => {
|
||||
return {
|
||||
innerWidth: window.innerWidth,
|
||||
@ -44,9 +44,9 @@ it('should return correct outerWidth and outerHeight', async ({page}) => {
|
||||
expect(size.outerHeight >= size.innerHeight).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should emulate device width', async ({page, server}) => {
|
||||
expect(page.viewportSize()).toEqual({width: 1280, height: 720});
|
||||
await page.setViewportSize({width: 200, height: 200});
|
||||
it('should emulate device width', async ({ page, server }) => {
|
||||
expect(page.viewportSize()).toEqual({ width: 1280, height: 720 });
|
||||
await page.setViewportSize({ width: 200, height: 200 });
|
||||
expect(await page.evaluate(() => window.screen.width)).toBe(200);
|
||||
expect(await page.evaluate(() => matchMedia('(min-device-width: 100px)').matches)).toBe(true);
|
||||
expect(await page.evaluate(() => matchMedia('(min-device-width: 300px)').matches)).toBe(false);
|
||||
@ -54,7 +54,7 @@ it('should emulate device width', async ({page, server}) => {
|
||||
expect(await page.evaluate(() => matchMedia('(max-device-width: 300px)').matches)).toBe(true);
|
||||
expect(await page.evaluate(() => matchMedia('(device-width: 500px)').matches)).toBe(false);
|
||||
expect(await page.evaluate(() => matchMedia('(device-width: 200px)').matches)).toBe(true);
|
||||
await page.setViewportSize({width: 500, height: 500});
|
||||
await page.setViewportSize({ width: 500, height: 500 });
|
||||
expect(await page.evaluate(() => window.screen.width)).toBe(500);
|
||||
expect(await page.evaluate(() => matchMedia('(min-device-width: 400px)').matches)).toBe(true);
|
||||
expect(await page.evaluate(() => matchMedia('(min-device-width: 600px)').matches)).toBe(false);
|
||||
@ -64,9 +64,9 @@ it('should emulate device width', async ({page, server}) => {
|
||||
expect(await page.evaluate(() => matchMedia('(device-width: 500px)').matches)).toBe(true);
|
||||
});
|
||||
|
||||
it('should emulate device height', async ({page, server}) => {
|
||||
expect(page.viewportSize()).toEqual({width: 1280, height: 720});
|
||||
await page.setViewportSize({width: 200, height: 200});
|
||||
it('should emulate device height', async ({ page, server }) => {
|
||||
expect(page.viewportSize()).toEqual({ width: 1280, height: 720 });
|
||||
await page.setViewportSize({ width: 200, height: 200 });
|
||||
expect(await page.evaluate(() => window.screen.height)).toBe(200);
|
||||
expect(await page.evaluate(() => matchMedia('(min-device-height: 100px)').matches)).toBe(true);
|
||||
expect(await page.evaluate(() => matchMedia('(min-device-height: 300px)').matches)).toBe(false);
|
||||
@ -74,7 +74,7 @@ it('should emulate device height', async ({page, server}) => {
|
||||
expect(await page.evaluate(() => matchMedia('(max-device-height: 300px)').matches)).toBe(true);
|
||||
expect(await page.evaluate(() => matchMedia('(device-height: 500px)').matches)).toBe(false);
|
||||
expect(await page.evaluate(() => matchMedia('(device-height: 200px)').matches)).toBe(true);
|
||||
await page.setViewportSize({width: 500, height: 500});
|
||||
await page.setViewportSize({ width: 500, height: 500 });
|
||||
expect(await page.evaluate(() => window.screen.height)).toBe(500);
|
||||
expect(await page.evaluate(() => matchMedia('(min-device-height: 400px)').matches)).toBe(true);
|
||||
expect(await page.evaluate(() => matchMedia('(min-device-height: 600px)').matches)).toBe(false);
|
||||
@ -84,20 +84,20 @@ it('should emulate device height', async ({page, server}) => {
|
||||
expect(await page.evaluate(() => matchMedia('(device-height: 500px)').matches)).toBe(true);
|
||||
});
|
||||
|
||||
it('should emulate availWidth and availHeight', async ({page}) => {
|
||||
await page.setViewportSize({width: 500, height: 600});
|
||||
it('should emulate availWidth and availHeight', async ({ page }) => {
|
||||
await page.setViewportSize({ width: 500, height: 600 });
|
||||
expect(await page.evaluate(() => window.screen.availWidth)).toBe(500);
|
||||
expect(await page.evaluate(() => window.screen.availHeight)).toBe(600);
|
||||
});
|
||||
|
||||
it('should not have touch by default', async ({page, server}) => {
|
||||
it('should not have touch by default', async ({ page, server }) => {
|
||||
await page.goto(server.PREFIX + '/mobile.html');
|
||||
expect(await page.evaluate(() => 'ontouchstart' in window)).toBe(false);
|
||||
await page.goto(server.PREFIX + '/detect-touch.html');
|
||||
expect(await page.evaluate(() => document.body.textContent.trim())).toBe('NO');
|
||||
});
|
||||
|
||||
browserTest('should support touch with null viewport', async ({browser, server}) => {
|
||||
browserTest('should support touch with null viewport', async ({ browser, server }) => {
|
||||
const context = await browser.newContext({ viewport: null, hasTouch: true });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.PREFIX + '/mobile.html');
|
||||
@ -105,14 +105,14 @@ browserTest('should support touch with null viewport', async ({browser, server})
|
||||
await context.close();
|
||||
});
|
||||
|
||||
browserTest('should report null viewportSize when given null viewport', async ({browser, server}) => {
|
||||
browserTest('should report null viewportSize when given null viewport', async ({ browser, server }) => {
|
||||
const context = await browser.newContext({ viewport: null });
|
||||
const page = await context.newPage();
|
||||
expect(page.viewportSize()).toBe(null);
|
||||
await context.close();
|
||||
});
|
||||
|
||||
browserTest('should drag with high dpi', async ({ browser, server}) => {
|
||||
browserTest('should drag with high dpi', async ({ browser, server }) => {
|
||||
const page = await browser.newPage({ deviceScaleFactor: 2 });
|
||||
await page.goto(server.PREFIX + '/drag-n-drop.html');
|
||||
await page.hover('#source');
|
||||
|
@ -26,13 +26,13 @@ test('browserType.executablePath should work', async ({ browserType, channel, br
|
||||
expect(fs.existsSync(executablePath)).toBe(true);
|
||||
});
|
||||
|
||||
test('browserType.name should work', async ({browserType, browserName}) => {
|
||||
test('browserType.name should work', async ({ browserType, browserName }) => {
|
||||
expect(browserType.name()).toBe(browserName);
|
||||
});
|
||||
|
||||
test('should throw when trying to connect with not-chromium', async ({ browserType, browserName }) => {
|
||||
test.skip(browserName === 'chromium');
|
||||
|
||||
const error = await browserType.connectOverCDP({endpointURL: 'ws://foo'}).catch(e => e);
|
||||
const error = await browserType.connectOverCDP({ endpointURL: 'ws://foo' }).catch(e => e);
|
||||
expect(error.message).toBe('Connecting over CDP is only supported in Chromium.');
|
||||
});
|
||||
|
@ -24,7 +24,7 @@ import { suppressCertificateWarning } from './config/utils';
|
||||
|
||||
test.slow(true, 'All connect tests are slow');
|
||||
|
||||
test('should connect over wss', async ({browserType , startRemoteServer, httpsServer, mode}) => {
|
||||
test('should connect over wss', async ({ browserType , startRemoteServer, httpsServer, mode }) => {
|
||||
test.skip(mode !== 'default'); // Out of process transport does not allow us to set env vars dynamically.
|
||||
const remoteServer = await startRemoteServer();
|
||||
|
||||
@ -60,7 +60,7 @@ test('should connect over wss', async ({browserType , startRemoteServer, httpsSe
|
||||
}
|
||||
});
|
||||
|
||||
test('should be able to reconnect to a browser', async ({browserType, startRemoteServer, server}) => {
|
||||
test('should be able to reconnect to a browser', async ({ browserType, startRemoteServer, server }) => {
|
||||
const remoteServer = await startRemoteServer();
|
||||
{
|
||||
const browser = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
||||
@ -80,7 +80,7 @@ test('should be able to reconnect to a browser', async ({browserType, startRemot
|
||||
}
|
||||
});
|
||||
|
||||
test('should be able to connect two browsers at the same time', async ({browserType, startRemoteServer}) => {
|
||||
test('should be able to connect two browsers at the same time', async ({ browserType, startRemoteServer }) => {
|
||||
const remoteServer = await startRemoteServer();
|
||||
|
||||
const browser1 = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
||||
@ -102,7 +102,7 @@ test('should be able to connect two browsers at the same time', async ({browserT
|
||||
await browser2.close();
|
||||
});
|
||||
|
||||
test('should timeout in socket while connecting', async ({browserType, startRemoteServer, server}) => {
|
||||
test('should timeout in socket while connecting', async ({ browserType, startRemoteServer, server }) => {
|
||||
const e = await browserType.connect({
|
||||
wsEndpoint: `ws://localhost:${server.PORT}/ws-slow`,
|
||||
timeout: 1000,
|
||||
@ -110,7 +110,7 @@ test('should timeout in socket while connecting', async ({browserType, startRemo
|
||||
expect(e.message).toContain('browserType.connect: Opening handshake has timed out');
|
||||
});
|
||||
|
||||
test('should timeout in connect while connecting', async ({browserType, startRemoteServer, server}) => {
|
||||
test('should timeout in connect while connecting', async ({ browserType, startRemoteServer, server }) => {
|
||||
const e = await browserType.connect({
|
||||
wsEndpoint: `ws://localhost:${server.PORT}/ws`,
|
||||
timeout: 100,
|
||||
@ -118,7 +118,7 @@ test('should timeout in connect while connecting', async ({browserType, startRem
|
||||
expect(e.message).toContain('browserType.connect: Timeout 100ms exceeded');
|
||||
});
|
||||
|
||||
test('should send extra headers with connect request', async ({browserType, startRemoteServer, server}) => {
|
||||
test('should send extra headers with connect request', async ({ browserType, startRemoteServer, server }) => {
|
||||
const [request] = await Promise.all([
|
||||
server.waitForWebSocketConnectionRequest(),
|
||||
browserType.connect({
|
||||
@ -134,7 +134,7 @@ test('should send extra headers with connect request', async ({browserType, star
|
||||
expect(request.headers['foo']).toBe('bar');
|
||||
});
|
||||
|
||||
test('should send default User-Agent header with connect request', async ({browserType, startRemoteServer, server}) => {
|
||||
test('should send default User-Agent header with connect request', async ({ browserType, startRemoteServer, server }) => {
|
||||
const [request] = await Promise.all([
|
||||
server.waitForWebSocketConnectionRequest(),
|
||||
browserType.connect({
|
||||
@ -149,7 +149,7 @@ test('should send default User-Agent header with connect request', async ({brows
|
||||
expect(request.headers['foo']).toBe('bar');
|
||||
});
|
||||
|
||||
test('should support slowmo option', async ({browserType, startRemoteServer}) => {
|
||||
test('should support slowmo option', async ({ browserType, startRemoteServer }) => {
|
||||
const remoteServer = await startRemoteServer();
|
||||
|
||||
const browser1 = await browserType.connect(remoteServer.wsEndpoint(), { slowMo: 200 });
|
||||
@ -159,7 +159,7 @@ test('should support slowmo option', async ({browserType, startRemoteServer}) =>
|
||||
expect(Date.now() - start).toBeGreaterThan(199);
|
||||
});
|
||||
|
||||
test('disconnected event should be emitted when browser is closed or server is closed', async ({browserType, startRemoteServer}) => {
|
||||
test('disconnected event should be emitted when browser is closed or server is closed', async ({ browserType, startRemoteServer }) => {
|
||||
const remoteServer = await startRemoteServer();
|
||||
|
||||
const browser1 = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
||||
@ -188,7 +188,7 @@ test('disconnected event should be emitted when browser is closed or server is c
|
||||
expect(disconnected2).toBe(1);
|
||||
});
|
||||
|
||||
test('disconnected event should have browser as argument', async ({browserType, startRemoteServer}) => {
|
||||
test('disconnected event should have browser as argument', async ({ browserType, startRemoteServer }) => {
|
||||
const remoteServer = await startRemoteServer();
|
||||
const browser = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
||||
const [disconnected] = await Promise.all([
|
||||
@ -198,7 +198,7 @@ test('disconnected event should have browser as argument', async ({browserType,
|
||||
expect(disconnected).toBe(browser);
|
||||
});
|
||||
|
||||
test('should handle exceptions during connect', async ({browserType, startRemoteServer, mode}) => {
|
||||
test('should handle exceptions during connect', async ({ browserType, startRemoteServer, mode }) => {
|
||||
test.skip(mode !== 'default');
|
||||
|
||||
const remoteServer = await startRemoteServer();
|
||||
@ -207,7 +207,7 @@ test('should handle exceptions during connect', async ({browserType, startRemote
|
||||
expect(error.message).toContain('Dummy');
|
||||
});
|
||||
|
||||
test('should set the browser connected state', async ({browserType, startRemoteServer}) => {
|
||||
test('should set the browser connected state', async ({ browserType, startRemoteServer }) => {
|
||||
const remoteServer = await startRemoteServer();
|
||||
const remote = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
||||
expect(remote.isConnected()).toBe(true);
|
||||
@ -215,7 +215,7 @@ test('should set the browser connected state', async ({browserType, startRemoteS
|
||||
expect(remote.isConnected()).toBe(false);
|
||||
});
|
||||
|
||||
test('should throw when used after isConnected returns false', async ({browserType, startRemoteServer}) => {
|
||||
test('should throw when used after isConnected returns false', async ({ browserType, startRemoteServer }) => {
|
||||
const remoteServer = await startRemoteServer();
|
||||
const browser = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
||||
const page = await browser.newPage();
|
||||
@ -228,7 +228,7 @@ test('should throw when used after isConnected returns false', async ({browserTy
|
||||
expect(error.message).toContain('has been closed');
|
||||
});
|
||||
|
||||
test('should throw when calling waitForNavigation after disconnect', async ({browserType, startRemoteServer}) => {
|
||||
test('should throw when calling waitForNavigation after disconnect', async ({ browserType, startRemoteServer }) => {
|
||||
const remoteServer = await startRemoteServer();
|
||||
const browser = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
||||
const page = await browser.newPage();
|
||||
@ -241,19 +241,19 @@ test('should throw when calling waitForNavigation after disconnect', async ({bro
|
||||
expect(error.message).toContain('Navigation failed because page was closed');
|
||||
});
|
||||
|
||||
test('should reject navigation when browser closes', async ({browserType, startRemoteServer, server}) => {
|
||||
test('should reject navigation when browser closes', async ({ browserType, startRemoteServer, server }) => {
|
||||
const remoteServer = await startRemoteServer();
|
||||
server.setRoute('/one-style.css', () => {});
|
||||
const browser = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
||||
const page = await browser.newPage();
|
||||
const navigationPromise = page.goto(server.PREFIX + '/one-style.html', {timeout: 60000}).catch(e => e);
|
||||
const navigationPromise = page.goto(server.PREFIX + '/one-style.html', { timeout: 60000 }).catch(e => e);
|
||||
await server.waitForRequest('/one-style.css');
|
||||
await browser.close();
|
||||
const error = await navigationPromise;
|
||||
expect(error.message).toContain('has been closed');
|
||||
});
|
||||
|
||||
test('should reject waitForSelector when browser closes', async ({browserType, startRemoteServer, server}) => {
|
||||
test('should reject waitForSelector when browser closes', async ({ browserType, startRemoteServer, server }) => {
|
||||
const remoteServer = await startRemoteServer();
|
||||
server.setRoute('/empty.html', () => {});
|
||||
const browser = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
||||
@ -268,7 +268,7 @@ test('should reject waitForSelector when browser closes', async ({browserType, s
|
||||
expect(error.message).toContain('has been closed');
|
||||
});
|
||||
|
||||
test('should emit close events on pages and contexts', async ({browserType, startRemoteServer}) => {
|
||||
test('should emit close events on pages and contexts', async ({ browserType, startRemoteServer }) => {
|
||||
const remoteServer = await startRemoteServer();
|
||||
const browser = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
||||
const context = await browser.newContext();
|
||||
@ -282,7 +282,7 @@ test('should emit close events on pages and contexts', async ({browserType, star
|
||||
expect(pageClosed).toBeTruthy();
|
||||
});
|
||||
|
||||
test('should terminate network waiters', async ({browserType, startRemoteServer, server}) => {
|
||||
test('should terminate network waiters', async ({ browserType, startRemoteServer, server }) => {
|
||||
const remoteServer = await startRemoteServer();
|
||||
const browser = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
||||
const newPage = await browser.newPage();
|
||||
@ -339,7 +339,7 @@ test('should respect selectors', async ({ playwright, browserType, startRemoteSe
|
||||
await browser1.close();
|
||||
});
|
||||
|
||||
test('should not throw on close after disconnect', async ({browserType, startRemoteServer}) => {
|
||||
test('should not throw on close after disconnect', async ({ browserType, startRemoteServer }) => {
|
||||
const remoteServer = await startRemoteServer();
|
||||
const browser = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
||||
await browser.newPage();
|
||||
@ -350,7 +350,7 @@ test('should not throw on close after disconnect', async ({browserType, startRem
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
test('should not throw on context.close after disconnect', async ({browserType, startRemoteServer}) => {
|
||||
test('should not throw on context.close after disconnect', async ({ browserType, startRemoteServer }) => {
|
||||
const remoteServer = await startRemoteServer();
|
||||
const browser = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
||||
const context = await browser.newContext();
|
||||
@ -362,7 +362,7 @@ test('should not throw on context.close after disconnect', async ({browserType,
|
||||
await context.close();
|
||||
});
|
||||
|
||||
test('should not throw on page.close after disconnect', async ({browserType, startRemoteServer}) => {
|
||||
test('should not throw on page.close after disconnect', async ({ browserType, startRemoteServer }) => {
|
||||
const remoteServer = await startRemoteServer();
|
||||
const browser = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
||||
const page = await browser.newPage();
|
||||
@ -373,7 +373,7 @@ test('should not throw on page.close after disconnect', async ({browserType, sta
|
||||
await page.close();
|
||||
});
|
||||
|
||||
test('should saveAs videos from remote browser', async ({browserType, startRemoteServer}, testInfo) => {
|
||||
test('should saveAs videos from remote browser', async ({ browserType, startRemoteServer }, testInfo) => {
|
||||
const remoteServer = await startRemoteServer();
|
||||
const browser = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
||||
const videosPath = testInfo.outputPath();
|
||||
@ -392,7 +392,7 @@ test('should saveAs videos from remote browser', async ({browserType, startRemot
|
||||
expect(error.message).toContain('Path is not available when using browserType.connect(). Use saveAs() to save a local copy.');
|
||||
});
|
||||
|
||||
test('should be able to connect 20 times to a single server without warnings', async ({browserType, startRemoteServer}) => {
|
||||
test('should be able to connect 20 times to a single server without warnings', async ({ browserType, startRemoteServer }) => {
|
||||
const remoteServer = await startRemoteServer();
|
||||
|
||||
let warning = null;
|
||||
@ -408,7 +408,7 @@ test('should be able to connect 20 times to a single server without warnings', a
|
||||
expect(warning).toBe(null);
|
||||
});
|
||||
|
||||
test('should save download', async ({server, browserType, startRemoteServer}, testInfo) => {
|
||||
test('should save download', async ({ server, browserType, startRemoteServer }, testInfo) => {
|
||||
server.setRoute('/download', (req, res) => {
|
||||
res.setHeader('Content-Type', 'application/octet-stream');
|
||||
res.setHeader('Content-Disposition', 'attachment');
|
||||
@ -432,7 +432,7 @@ test('should save download', async ({server, browserType, startRemoteServer}, te
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
test('should error when saving download after deletion', async ({server, browserType, startRemoteServer}, testInfo) => {
|
||||
test('should error when saving download after deletion', async ({ server, browserType, startRemoteServer }, testInfo) => {
|
||||
server.setRoute('/download', (req, res) => {
|
||||
res.setHeader('Content-Type', 'application/octet-stream');
|
||||
res.setHeader('Content-Disposition', 'attachment');
|
||||
@ -454,19 +454,19 @@ test('should error when saving download after deletion', async ({server, browser
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
test('should work with cluster', async ({browserType, startRemoteServer}) => {
|
||||
test('should work with cluster', async ({ browserType, startRemoteServer }) => {
|
||||
const remoteServer = await startRemoteServer({ inCluster: true });
|
||||
const browser = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
||||
const page = await browser.newPage();
|
||||
expect(await page.evaluate('1 + 2')).toBe(3);
|
||||
});
|
||||
|
||||
test('should properly disconnect when connection closes from the client side', async ({browserType, startRemoteServer, server}) => {
|
||||
test('should properly disconnect when connection closes from the client side', async ({ browserType, startRemoteServer, server }) => {
|
||||
server.setRoute('/one-style.css', () => {});
|
||||
const remoteServer = await startRemoteServer();
|
||||
const browser = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
||||
const page = await browser.newPage();
|
||||
const navigationPromise = page.goto(server.PREFIX + '/one-style.html', {timeout: 60000}).catch(e => e);
|
||||
const navigationPromise = page.goto(server.PREFIX + '/one-style.html', { timeout: 60000 }).catch(e => e);
|
||||
const waitForNavigationPromise = page.waitForNavigation().catch(e => e);
|
||||
|
||||
const disconnectedPromise = new Promise(f => browser.once('disconnected', f));
|
||||
@ -481,14 +481,14 @@ test('should properly disconnect when connection closes from the client side', a
|
||||
expect((await page.waitForNavigation().catch(e => e)).message).toContain('Navigation failed because page was closed');
|
||||
});
|
||||
|
||||
test('should properly disconnect when connection closes from the server side', async ({browserType, startRemoteServer, server, platform}) => {
|
||||
test('should properly disconnect when connection closes from the server side', async ({ browserType, startRemoteServer, server, platform }) => {
|
||||
test.skip(platform === 'win32', 'Cannot send signals');
|
||||
|
||||
server.setRoute('/one-style.css', () => {});
|
||||
const remoteServer = await startRemoteServer({ disconnectOnSIGHUP: true });
|
||||
const browser = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
||||
const page = await browser.newPage();
|
||||
const navigationPromise = page.goto(server.PREFIX + '/one-style.html', {timeout: 60000}).catch(e => e);
|
||||
const navigationPromise = page.goto(server.PREFIX + '/one-style.html', { timeout: 60000 }).catch(e => e);
|
||||
const waitForNavigationPromise = page.waitForNavigation().catch(e => e);
|
||||
|
||||
const disconnectedPromise = new Promise(f => browser.once('disconnected', f));
|
||||
@ -503,7 +503,7 @@ test('should properly disconnect when connection closes from the server side', a
|
||||
expect((await page.waitForNavigation().catch(e => e)).message).toContain('Navigation failed because page was closed');
|
||||
});
|
||||
|
||||
test('should be able to connect when the wsEndpont is passed as the first argument', async ({browserType, startRemoteServer}) => {
|
||||
test('should be able to connect when the wsEndpont is passed as the first argument', async ({ browserType, startRemoteServer }) => {
|
||||
const remoteServer = await startRemoteServer();
|
||||
const browser = await browserType.connect(remoteServer.wsEndpoint());
|
||||
const page = await browser.newPage();
|
||||
@ -511,7 +511,7 @@ test('should be able to connect when the wsEndpont is passed as the first argume
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
test('should save har', async ({browserType, startRemoteServer, server}, testInfo) => {
|
||||
test('should save har', async ({ browserType, startRemoteServer, server }, testInfo) => {
|
||||
const remoteServer = await startRemoteServer();
|
||||
const browser = await browserType.connect(remoteServer.wsEndpoint());
|
||||
const harPath = testInfo.outputPath('test.har');
|
||||
|
@ -18,49 +18,49 @@
|
||||
import { playwrightTest as it, expect } from './config/browserTest';
|
||||
|
||||
it.describe('launch server', () => {
|
||||
it.skip(({ mode}) => mode !== 'default');
|
||||
it.skip(({ mode }) => mode !== 'default');
|
||||
|
||||
it('should work', async ({browserType, browserOptions}) => {
|
||||
it('should work', async ({ browserType, browserOptions }) => {
|
||||
const browserServer = await browserType.launchServer(browserOptions);
|
||||
expect(browserServer.wsEndpoint()).not.toBe(null);
|
||||
await browserServer.close();
|
||||
});
|
||||
|
||||
it('should work with port', async ({browserType, browserOptions}, testInfo) => {
|
||||
it('should work with port', async ({ browserType, browserOptions }, testInfo) => {
|
||||
const port = 8800 + testInfo.workerIndex;
|
||||
const browserServer = await browserType.launchServer({ ...browserOptions, port });
|
||||
expect(browserServer.wsEndpoint()).toContain(String(port));
|
||||
await browserServer.close();
|
||||
});
|
||||
|
||||
it('should work with wsPath', async ({browserType, browserOptions}) => {
|
||||
it('should work with wsPath', async ({ browserType, browserOptions }) => {
|
||||
const wsPath = '/unguessable-token';
|
||||
const browserServer = await browserType.launchServer({ ...browserOptions, wsPath });
|
||||
expect(browserServer.wsEndpoint()).toMatch(/:\d+\/unguessable-token$/);
|
||||
await browserServer.close();
|
||||
});
|
||||
|
||||
it('should work when wsPath is missing leading slash', async ({browserType, browserOptions}) => {
|
||||
it('should work when wsPath is missing leading slash', async ({ browserType, browserOptions }) => {
|
||||
const wsPath = 'unguessable-token';
|
||||
const browserServer = await browserType.launchServer({ ...browserOptions, wsPath });
|
||||
expect(browserServer.wsEndpoint()).toMatch(/:\d+\/unguessable-token$/);
|
||||
await browserServer.close();
|
||||
});
|
||||
|
||||
it('should default to random wsPath', async ({browserType, browserOptions}) => {
|
||||
it('should default to random wsPath', async ({ browserType, browserOptions }) => {
|
||||
const browserServer = await browserType.launchServer({ ...browserOptions });
|
||||
expect(browserServer.wsEndpoint()).toMatch(/:\d+\/[a-f\d]{32}$/);
|
||||
await browserServer.close();
|
||||
});
|
||||
|
||||
it('should provide an error when ws endpoint is incorrect', async ({browserType, browserOptions}) => {
|
||||
it('should provide an error when ws endpoint is incorrect', async ({ browserType, browserOptions }) => {
|
||||
const browserServer = await browserType.launchServer(browserOptions);
|
||||
const error = await browserType.connect({ wsEndpoint: browserServer.wsEndpoint() + '-foo' }).catch(e => e);
|
||||
await browserServer.close();
|
||||
expect(error.message).toContain('Unexpected server response: 400');
|
||||
});
|
||||
|
||||
it('should fire "close" event during kill', async ({browserType, browserOptions}) => {
|
||||
it('should fire "close" event during kill', async ({ browserType, browserOptions }) => {
|
||||
const order = [];
|
||||
const browserServer = await browserType.launchServer(browserOptions);
|
||||
const closedPromise = new Promise<void>(f => browserServer.on('close', () => {
|
||||
@ -74,13 +74,13 @@ it.describe('launch server', () => {
|
||||
expect(order).toEqual(['closed', 'killed']);
|
||||
});
|
||||
|
||||
it('should return child_process instance', async ({browserType, browserOptions}) => {
|
||||
it('should return child_process instance', async ({ browserType, browserOptions }) => {
|
||||
const browserServer = await browserType.launchServer(browserOptions);
|
||||
expect(browserServer.process().pid).toBeGreaterThan(0);
|
||||
await browserServer.close();
|
||||
});
|
||||
|
||||
it('should fire close event', async ({browserType, browserOptions}) => {
|
||||
it('should fire close event', async ({ browserType, browserOptions }) => {
|
||||
const browserServer = await browserType.launchServer(browserOptions);
|
||||
const [result] = await Promise.all([
|
||||
// @ts-expect-error The signal parameter is not documented.
|
||||
@ -91,7 +91,7 @@ it.describe('launch server', () => {
|
||||
expect(result['signal']).toBe(null);
|
||||
});
|
||||
|
||||
it('should log protocol', async ({browserType, browserOptions}) => {
|
||||
it('should log protocol', async ({ browserType, browserOptions }) => {
|
||||
const logs: string[] = [];
|
||||
const logger = {
|
||||
isEnabled(name: string) {
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import { playwrightTest as it, expect } from './config/browserTest';
|
||||
|
||||
it('should reject all promises when browser is closed', async ({browserType, browserOptions}) => {
|
||||
it('should reject all promises when browser is closed', async ({ browserType, browserOptions }) => {
|
||||
const browser = await browserType.launch(browserOptions);
|
||||
const page = await (await browser.newContext()).newPage();
|
||||
let error = null;
|
||||
@ -29,33 +29,33 @@ it('should reject all promises when browser is closed', async ({browserType, bro
|
||||
expect(error.message).toContain(' closed');
|
||||
});
|
||||
|
||||
it('should throw if userDataDir option is passed', async ({browserType, browserOptions}) => {
|
||||
it('should throw if userDataDir option is passed', async ({ browserType, browserOptions }) => {
|
||||
let waitError = null;
|
||||
const options = Object.assign({}, browserOptions, {userDataDir: 'random-path'});
|
||||
const options = Object.assign({}, browserOptions, { userDataDir: 'random-path' });
|
||||
await browserType.launch(options).catch(e => waitError = e);
|
||||
expect(waitError.message).toContain('userDataDir option is not supported in `browserType.launch`. Use `browserType.launchPersistentContext` instead');
|
||||
});
|
||||
|
||||
it('should throw if userDataDir is passed as an argument', async ({browserType, browserOptions}) => {
|
||||
it('should throw if userDataDir is passed as an argument', async ({ browserType, browserOptions }) => {
|
||||
let waitError = null;
|
||||
const options = Object.assign({}, browserOptions, {args: ['--user-data-dir=random-path', '--profile=random-path']});
|
||||
const options = Object.assign({}, browserOptions, { args: ['--user-data-dir=random-path', '--profile=random-path'] });
|
||||
await browserType.launch(options).catch(e => waitError = e);
|
||||
expect(waitError.message).toContain('Pass userDataDir parameter to `browserType.launchPersistentContext');
|
||||
});
|
||||
|
||||
it('should throw if port option is passed', async ({browserType, browserOptions}) => {
|
||||
const options = Object.assign({}, browserOptions, {port: 1234});
|
||||
it('should throw if port option is passed', async ({ browserType, browserOptions }) => {
|
||||
const options = Object.assign({}, browserOptions, { port: 1234 });
|
||||
const error = await browserType.launch(options).catch(e => e);
|
||||
expect(error.message).toContain('Cannot specify a port without launching as a server.');
|
||||
});
|
||||
|
||||
it('should throw if port option is passed for persistent context', async ({browserType, browserOptions}) => {
|
||||
const options = Object.assign({}, browserOptions, {port: 1234});
|
||||
it('should throw if port option is passed for persistent context', async ({ browserType, browserOptions }) => {
|
||||
const options = Object.assign({}, browserOptions, { port: 1234 });
|
||||
const error = await browserType.launchPersistentContext('foo', options).catch(e => e);
|
||||
expect(error.message).toContain('Cannot specify a port without launching as a server.');
|
||||
});
|
||||
|
||||
it('should throw if page argument is passed', async ({browserType, browserOptions, browserName}) => {
|
||||
it('should throw if page argument is passed', async ({ browserType, browserOptions, browserName }) => {
|
||||
it.skip(browserName === 'firefox');
|
||||
|
||||
let waitError = null;
|
||||
@ -64,21 +64,21 @@ it('should throw if page argument is passed', async ({browserType, browserOption
|
||||
expect(waitError.message).toContain('can not specify page');
|
||||
});
|
||||
|
||||
it('should reject if launched browser fails immediately', async ({browserType, browserOptions, asset}) => {
|
||||
const options = Object.assign({}, browserOptions, {executablePath: asset('dummy_bad_browser_executable.js')});
|
||||
it('should reject if launched browser fails immediately', async ({ browserType, browserOptions, asset }) => {
|
||||
const options = Object.assign({}, browserOptions, { executablePath: asset('dummy_bad_browser_executable.js') });
|
||||
let waitError = null;
|
||||
await browserType.launch(options).catch(e => waitError = e);
|
||||
expect(waitError.message).toContain('== logs ==');
|
||||
});
|
||||
|
||||
it('should reject if executable path is invalid', async ({browserType, browserOptions}) => {
|
||||
it('should reject if executable path is invalid', async ({ browserType, browserOptions }) => {
|
||||
let waitError = null;
|
||||
const options = Object.assign({}, browserOptions, {executablePath: 'random-invalid-path'});
|
||||
const options = Object.assign({}, browserOptions, { executablePath: 'random-invalid-path' });
|
||||
await browserType.launch(options).catch(e => waitError = e);
|
||||
expect(waitError.message).toContain('Failed to launch');
|
||||
});
|
||||
|
||||
it('should handle timeout', async ({browserType, browserOptions, mode}) => {
|
||||
it('should handle timeout', async ({ browserType, browserOptions, mode }) => {
|
||||
it.skip(mode !== 'default');
|
||||
|
||||
const options = { ...browserOptions, timeout: 5000, __testHookBeforeCreateBrowser: () => new Promise(f => setTimeout(f, 6000)) };
|
||||
@ -88,7 +88,7 @@ it('should handle timeout', async ({browserType, browserOptions, mode}) => {
|
||||
expect(error.message).toContain(`<launched> pid=`);
|
||||
});
|
||||
|
||||
it('should handle exception', async ({browserType, browserOptions, mode}) => {
|
||||
it('should handle exception', async ({ browserType, browserOptions, mode }) => {
|
||||
it.skip(mode !== 'default');
|
||||
|
||||
const e = new Error('Dummy');
|
||||
@ -97,7 +97,7 @@ it('should handle exception', async ({browserType, browserOptions, mode}) => {
|
||||
expect(error.message).toContain('Dummy');
|
||||
});
|
||||
|
||||
it('should report launch log', async ({browserType, browserOptions, mode}) => {
|
||||
it('should report launch log', async ({ browserType, browserOptions, mode }) => {
|
||||
it.skip(mode !== 'default');
|
||||
|
||||
const e = new Error('Dummy');
|
||||
@ -106,13 +106,13 @@ it('should report launch log', async ({browserType, browserOptions, mode}) => {
|
||||
expect(error.message).toContain('<launching>');
|
||||
});
|
||||
|
||||
it('should accept objects as options', async ({browserType, browserOptions}) => {
|
||||
it('should accept objects as options', async ({ browserType, browserOptions }) => {
|
||||
// @ts-expect-error process is not a real option.
|
||||
const browser = await browserType.launch({ ...browserOptions, process });
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should fire close event for all contexts', async ({browserType, browserOptions}) => {
|
||||
it('should fire close event for all contexts', async ({ browserType, browserOptions }) => {
|
||||
const browser = await browserType.launch(browserOptions);
|
||||
const context = await browser.newContext();
|
||||
let closed = false;
|
||||
@ -121,7 +121,7 @@ it('should fire close event for all contexts', async ({browserType, browserOptio
|
||||
expect(closed).toBe(true);
|
||||
});
|
||||
|
||||
it('should be callable twice', async ({browserType, browserOptions}) => {
|
||||
it('should be callable twice', async ({ browserType, browserOptions }) => {
|
||||
const browser = await browserType.launch(browserOptions);
|
||||
await Promise.all([
|
||||
browser.close(),
|
||||
|
@ -18,7 +18,7 @@ import os from 'os';
|
||||
import url from 'url';
|
||||
import { contextTest as it, expect } from './config/browserTest';
|
||||
|
||||
it('SharedArrayBuffer should work', async function({contextFactory, httpsServer, browserName}) {
|
||||
it('SharedArrayBuffer should work', async function({ contextFactory, httpsServer, browserName }) {
|
||||
it.fail(browserName === 'webkit', 'no shared array buffer on webkit');
|
||||
const context = await contextFactory({ ignoreHTTPSErrors: true });
|
||||
const page = await context.newPage();
|
||||
@ -31,14 +31,14 @@ it('SharedArrayBuffer should work', async function({contextFactory, httpsServer,
|
||||
expect(await page.evaluate(() => typeof SharedArrayBuffer)).toBe('function');
|
||||
});
|
||||
|
||||
it('Web Assembly should work', async function({page, server, browserName, platform}) {
|
||||
it('Web Assembly should work', async function({ page, server, browserName, platform }) {
|
||||
it.fail(browserName === 'webkit' && platform === 'win32');
|
||||
|
||||
await page.goto(server.PREFIX + '/wasm/table2.html');
|
||||
expect(await page.evaluate('loadTable()')).toBe('42, 83');
|
||||
});
|
||||
|
||||
it('WebSocket should work', async ({page, server}) => {
|
||||
it('WebSocket should work', async ({ page, server }) => {
|
||||
server.sendOnWebSocketConnection('incoming');
|
||||
const value = await page.evaluate(port => {
|
||||
let cb;
|
||||
@ -51,7 +51,7 @@ it('WebSocket should work', async ({page, server}) => {
|
||||
expect(value).toBe('incoming');
|
||||
});
|
||||
|
||||
it('should respect CSP', async ({page, server}) => {
|
||||
it('should respect CSP', async ({ page, server }) => {
|
||||
server.setRoute('/empty.html', async (req, res) => {
|
||||
res.setHeader('Content-Security-Policy', `script-src 'unsafe-inline';`);
|
||||
res.end(`
|
||||
@ -65,7 +65,7 @@ it('should respect CSP', async ({page, server}) => {
|
||||
expect(await page.evaluate(() => window['testStatus'])).toBe('SUCCESS');
|
||||
});
|
||||
|
||||
it('should play video', async ({page, asset, browserName, platform}) => {
|
||||
it('should play video', async ({ page, asset, browserName, platform }) => {
|
||||
// TODO: the test passes on Windows locally but fails on GitHub Action bot,
|
||||
// apparently due to a Media Pack issue in the Windows Server.
|
||||
// Also the test is very flaky on Linux WebKit.
|
||||
@ -82,7 +82,7 @@ it('should play video', async ({page, asset, browserName, platform}) => {
|
||||
await page.$eval('video', v => v.pause());
|
||||
});
|
||||
|
||||
it('should support webgl', async ({page, browserName, headless}) => {
|
||||
it('should support webgl', async ({ page, browserName, headless }) => {
|
||||
it.fixme(browserName === 'firefox' && headless);
|
||||
|
||||
const hasWebGL = await page.evaluate(() => {
|
||||
@ -92,7 +92,7 @@ it('should support webgl', async ({page, browserName, headless}) => {
|
||||
expect(hasWebGL).toBe(true);
|
||||
});
|
||||
|
||||
it('should support webgl 2', async ({page, browserName, headless}) => {
|
||||
it('should support webgl 2', async ({ page, browserName, headless }) => {
|
||||
it.skip(browserName === 'webkit', 'WebKit doesn\'t have webgl2 enabled yet upstream.');
|
||||
it.fixme(browserName === 'firefox' && headless);
|
||||
it.fixme(browserName === 'chromium' && !headless, 'chromium doesn\'t like webgl2 when running under xvfb');
|
||||
|
@ -22,7 +22,7 @@ import { playwrightTest as it, expect } from './config/browserTest';
|
||||
// Otherwise, a browser launched for other tests in this worker will affect the expectations.
|
||||
it.use({ args: [] });
|
||||
|
||||
it('should scope context handles', async ({browserType, browserOptions, server}) => {
|
||||
it('should scope context handles', async ({ browserType, browserOptions, server }) => {
|
||||
const browser = await browserType.launch(browserOptions);
|
||||
const GOLDEN_PRECONDITION = {
|
||||
_guid: '',
|
||||
@ -53,10 +53,10 @@ it('should scope context handles', async ({browserType, browserOptions, server})
|
||||
{ _guid: 'browser', objects: [
|
||||
{ _guid: 'browser-context', objects: [
|
||||
{ _guid: 'frame', objects: [] },
|
||||
{ _guid: 'page', objects: []},
|
||||
{ _guid: 'page', objects: [] },
|
||||
{ _guid: 'request', objects: [] },
|
||||
{ _guid: 'response', objects: [] },
|
||||
]},
|
||||
] },
|
||||
{ _guid: 'fetchRequest', objects: [] }
|
||||
] },
|
||||
] },
|
||||
@ -71,7 +71,7 @@ it('should scope context handles', async ({browserType, browserOptions, server})
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should scope CDPSession handles', async ({browserType, browserOptions, browserName}) => {
|
||||
it('should scope CDPSession handles', async ({ browserType, browserOptions, browserName }) => {
|
||||
it.skip(browserName !== 'chromium');
|
||||
|
||||
const browser = await browserType.launch(browserOptions);
|
||||
@ -115,7 +115,7 @@ it('should scope CDPSession handles', async ({browserType, browserOptions, brows
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should scope browser handles', async ({browserType, browserOptions}) => {
|
||||
it('should scope browser handles', async ({ browserType, browserOptions }) => {
|
||||
const GOLDEN_PRECONDITION = {
|
||||
_guid: '',
|
||||
objects: [
|
||||
|
@ -21,7 +21,7 @@ import http from 'http';
|
||||
import { getUserAgent } from '../../lib/utils/utils';
|
||||
import { suppressCertificateWarning } from '../config/utils';
|
||||
|
||||
test('should create a worker from a service worker', async ({page, server}) => {
|
||||
test('should create a worker from a service worker', async ({ page, server }) => {
|
||||
const [worker] = await Promise.all([
|
||||
page.context().waitForEvent('serviceworker'),
|
||||
page.goto(server.PREFIX + '/serviceworkers/empty/sw.html')
|
||||
@ -29,7 +29,7 @@ test('should create a worker from a service worker', async ({page, server}) => {
|
||||
expect(await worker.evaluate(() => self.toString())).toBe('[object ServiceWorkerGlobalScope]');
|
||||
});
|
||||
|
||||
test('serviceWorkers() should return current workers', async ({page, server}) => {
|
||||
test('serviceWorkers() should return current workers', async ({ page, server }) => {
|
||||
const context = page.context();
|
||||
const [worker1] = await Promise.all([
|
||||
context.waitForEvent('serviceworker'),
|
||||
@ -48,7 +48,7 @@ test('serviceWorkers() should return current workers', async ({page, server}) =>
|
||||
expect(workers).toContain(worker2);
|
||||
});
|
||||
|
||||
test('should not create a worker from a shared worker', async ({page, server}) => {
|
||||
test('should not create a worker from a shared worker', async ({ page, server }) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
let serviceWorkerCreated;
|
||||
page.context().once('serviceworker', () => serviceWorkerCreated = true);
|
||||
@ -58,7 +58,7 @@ test('should not create a worker from a shared worker', async ({page, server}) =
|
||||
expect(serviceWorkerCreated).not.toBeTruthy();
|
||||
});
|
||||
|
||||
test('Page.route should work with intervention headers', async ({server, page}) => {
|
||||
test('Page.route should work with intervention headers', async ({ server, page }) => {
|
||||
server.setRoute('/intervention', (req, res) => res.end(`
|
||||
<script>
|
||||
document.write('<script src="${server.CROSS_PROCESS_PREFIX}/intervention.js">' + '</scr' + 'ipt>');
|
||||
@ -78,7 +78,7 @@ test('Page.route should work with intervention headers', async ({server, page})
|
||||
expect(serverRequest.headers.intervention).toContain('feature/5718547946799104');
|
||||
});
|
||||
|
||||
playwrightTest('should close service worker together with the context', async ({browserType, browserOptions, server}) => {
|
||||
playwrightTest('should close service worker together with the context', async ({ browserType, browserOptions, server }) => {
|
||||
const browser = await browserType.launch(browserOptions);
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
@ -169,7 +169,7 @@ playwrightTest('should connect to existing page with iframe and navigate', async
|
||||
}
|
||||
});
|
||||
|
||||
playwrightTest('should connect to existing service workers', async ({browserType, browserOptions, server}, testInfo) => {
|
||||
playwrightTest('should connect to existing service workers', async ({ browserType, browserOptions, server }, testInfo) => {
|
||||
const port = 9339 + testInfo.workerIndex;
|
||||
const browserServer = await browserType.launch({
|
||||
...browserOptions,
|
||||
@ -199,7 +199,7 @@ playwrightTest('should connect to existing service workers', async ({browserType
|
||||
}
|
||||
});
|
||||
|
||||
playwrightTest('should connect over a ws endpoint', async ({browserType, browserOptions, server}, testInfo) => {
|
||||
playwrightTest('should connect over a ws endpoint', async ({ browserType, browserOptions, server }, testInfo) => {
|
||||
const port = 9339 + testInfo.workerIndex;
|
||||
const browserServer = await browserType.launch({
|
||||
...browserOptions,
|
||||
@ -232,7 +232,7 @@ playwrightTest('should connect over a ws endpoint', async ({browserType, browser
|
||||
}
|
||||
});
|
||||
|
||||
playwrightTest('should send extra headers with connect request', async ({browserType, browserOptions, server}, testInfo) => {
|
||||
playwrightTest('should send extra headers with connect request', async ({ browserType, browserOptions, server }, testInfo) => {
|
||||
{
|
||||
const [request] = await Promise.all([
|
||||
server.waitForWebSocketConnectionRequest(),
|
||||
@ -265,7 +265,7 @@ playwrightTest('should send extra headers with connect request', async ({browser
|
||||
}
|
||||
});
|
||||
|
||||
playwrightTest('should send default User-Agent header with connect request', async ({browserType, browserOptions, server}, testInfo) => {
|
||||
playwrightTest('should send default User-Agent header with connect request', async ({ browserType, browserOptions, server }, testInfo) => {
|
||||
{
|
||||
const [request] = await Promise.all([
|
||||
server.waitForWebSocketConnectionRequest(),
|
||||
|
@ -16,20 +16,20 @@
|
||||
|
||||
import { contextTest as it, expect } from '../config/browserTest';
|
||||
|
||||
it('should work', async function({page, server}) {
|
||||
it('should work', async function({ page, server }) {
|
||||
await page.coverage.startCSSCoverage();
|
||||
await page.goto(server.PREFIX + '/csscoverage/simple.html');
|
||||
const coverage = await page.coverage.stopCSSCoverage();
|
||||
expect(coverage.length).toBe(1);
|
||||
expect(coverage[0].url).toContain('/csscoverage/simple.html');
|
||||
expect(coverage[0].ranges).toEqual([
|
||||
{start: 1, end: 22}
|
||||
{ start: 1, end: 22 }
|
||||
]);
|
||||
const range = coverage[0].ranges[0];
|
||||
expect(coverage[0].text.substring(range.start, range.end)).toBe('div { color: green; }');
|
||||
});
|
||||
|
||||
it('should report sourceURLs', async function({page, server}) {
|
||||
it('should report sourceURLs', async function({ page, server }) {
|
||||
await page.coverage.startCSSCoverage();
|
||||
await page.goto(server.PREFIX + '/csscoverage/sourceurl.html');
|
||||
const coverage = await page.coverage.stopCSSCoverage();
|
||||
@ -37,7 +37,7 @@ it('should report sourceURLs', async function({page, server}) {
|
||||
expect(coverage[0].url).toBe('nicename.css');
|
||||
});
|
||||
|
||||
it('should report multiple stylesheets', async function({page, server}) {
|
||||
it('should report multiple stylesheets', async function({ page, server }) {
|
||||
await page.coverage.startCSSCoverage();
|
||||
await page.goto(server.PREFIX + '/csscoverage/multiple.html');
|
||||
const coverage = await page.coverage.stopCSSCoverage();
|
||||
@ -47,7 +47,7 @@ it('should report multiple stylesheets', async function({page, server}) {
|
||||
expect(coverage[1].url).toContain('/csscoverage/stylesheet2.css');
|
||||
});
|
||||
|
||||
it('should report stylesheets that have no coverage', async function({page, server}) {
|
||||
it('should report stylesheets that have no coverage', async function({ page, server }) {
|
||||
await page.coverage.startCSSCoverage();
|
||||
await page.goto(server.PREFIX + '/csscoverage/unused.html');
|
||||
const coverage = await page.coverage.stopCSSCoverage();
|
||||
@ -56,18 +56,18 @@ it('should report stylesheets that have no coverage', async function({page, serv
|
||||
expect(coverage[0].ranges.length).toBe(0);
|
||||
});
|
||||
|
||||
it('should work with media queries', async function({page, server}) {
|
||||
it('should work with media queries', async function({ page, server }) {
|
||||
await page.coverage.startCSSCoverage();
|
||||
await page.goto(server.PREFIX + '/csscoverage/media.html');
|
||||
const coverage = await page.coverage.stopCSSCoverage();
|
||||
expect(coverage.length).toBe(1);
|
||||
expect(coverage[0].url).toContain('/csscoverage/media.html');
|
||||
expect(coverage[0].ranges).toEqual([
|
||||
{start: 17, end: 38}
|
||||
{ start: 17, end: 38 }
|
||||
]);
|
||||
});
|
||||
|
||||
it('should work with complicated usecases', async function({page, server}) {
|
||||
it('should work with complicated usecases', async function({ page, server }) {
|
||||
await page.coverage.startCSSCoverage();
|
||||
await page.goto(server.PREFIX + '/csscoverage/involved.html');
|
||||
const coverage: any = await page.coverage.stopCSSCoverage();
|
||||
@ -91,9 +91,9 @@ it('should work with complicated usecases', async function({page, server}) {
|
||||
);
|
||||
});
|
||||
|
||||
it('should ignore injected stylesheets', async function({page, server}) {
|
||||
it('should ignore injected stylesheets', async function({ page, server }) {
|
||||
await page.coverage.startCSSCoverage();
|
||||
await page.addStyleTag({content: 'body { margin: 10px;}'});
|
||||
await page.addStyleTag({ content: 'body { margin: 10px;}' });
|
||||
// trigger style recalc
|
||||
const margin = await page.evaluate(() => window.getComputedStyle(document.body).margin);
|
||||
expect(margin).toBe('10px');
|
||||
@ -101,15 +101,15 @@ it('should ignore injected stylesheets', async function({page, server}) {
|
||||
expect(coverage.length).toBe(0);
|
||||
});
|
||||
|
||||
it('should report stylesheets across navigations', async function({page, server}) {
|
||||
await page.coverage.startCSSCoverage({resetOnNavigation: false});
|
||||
it('should report stylesheets across navigations', async function({ page, server }) {
|
||||
await page.coverage.startCSSCoverage({ resetOnNavigation: false });
|
||||
await page.goto(server.PREFIX + '/csscoverage/multiple.html');
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const coverage = await page.coverage.stopCSSCoverage();
|
||||
expect(coverage.length).toBe(2);
|
||||
});
|
||||
|
||||
it('should NOT report scripts across navigations', async function({page, server}) {
|
||||
it('should NOT report scripts across navigations', async function({ page, server }) {
|
||||
await page.coverage.startCSSCoverage(); // Enabled by default.
|
||||
await page.goto(server.PREFIX + '/csscoverage/multiple.html');
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -117,7 +117,7 @@ it('should NOT report scripts across navigations', async function({page, server}
|
||||
expect(coverage.length).toBe(0);
|
||||
});
|
||||
|
||||
it('should work with a recently loaded stylesheet', async function({page, server}) {
|
||||
it('should work with a recently loaded stylesheet', async function({ page, server }) {
|
||||
await page.coverage.startCSSCoverage();
|
||||
await page.evaluate(async url => {
|
||||
document.body.textContent = 'hello, world';
|
||||
|
@ -18,7 +18,7 @@ import { contextTest as it, expect } from '../config/browserTest';
|
||||
|
||||
it.skip(({ trace }) => !!trace);
|
||||
|
||||
it('should work', async function({page, server}) {
|
||||
it('should work', async function({ page, server }) {
|
||||
await page.coverage.startJSCoverage();
|
||||
await page.goto(server.PREFIX + '/jscoverage/simple.html', { waitUntil: 'load' });
|
||||
const coverage = await page.coverage.stopJSCoverage();
|
||||
@ -27,7 +27,7 @@ it('should work', async function({page, server}) {
|
||||
expect(coverage[0].functions.find(f => f.functionName === 'foo').ranges[0].count).toEqual(1);
|
||||
});
|
||||
|
||||
it('should report sourceURLs', async function({page, server}) {
|
||||
it('should report sourceURLs', async function({ page, server }) {
|
||||
await page.coverage.startJSCoverage();
|
||||
await page.goto(server.PREFIX + '/jscoverage/sourceurl.html');
|
||||
const coverage = await page.coverage.stopJSCoverage();
|
||||
@ -35,22 +35,22 @@ it('should report sourceURLs', async function({page, server}) {
|
||||
expect(coverage[0].url).toBe('nicename.js');
|
||||
});
|
||||
|
||||
it('should ignore eval() scripts by default', async function({page, server}) {
|
||||
it('should ignore eval() scripts by default', async function({ page, server }) {
|
||||
await page.coverage.startJSCoverage();
|
||||
await page.goto(server.PREFIX + '/jscoverage/eval.html');
|
||||
const coverage = await page.coverage.stopJSCoverage();
|
||||
expect(coverage.length).toBe(1);
|
||||
});
|
||||
|
||||
it('shouldn\'t ignore eval() scripts if reportAnonymousScripts is true', async function({page, server}) {
|
||||
await page.coverage.startJSCoverage({reportAnonymousScripts: true});
|
||||
it('shouldn\'t ignore eval() scripts if reportAnonymousScripts is true', async function({ page, server }) {
|
||||
await page.coverage.startJSCoverage({ reportAnonymousScripts: true });
|
||||
await page.goto(server.PREFIX + '/jscoverage/eval.html');
|
||||
const coverage = await page.coverage.stopJSCoverage();
|
||||
expect(coverage.find(entry => entry.url === '').source).toBe('console.log("foo")');
|
||||
expect(coverage.length).toBe(2);
|
||||
});
|
||||
|
||||
it('should report multiple scripts', async function({page, server}) {
|
||||
it('should report multiple scripts', async function({ page, server }) {
|
||||
await page.coverage.startJSCoverage();
|
||||
await page.goto(server.PREFIX + '/jscoverage/multiple.html');
|
||||
const coverage = await page.coverage.stopJSCoverage();
|
||||
@ -60,15 +60,15 @@ it('should report multiple scripts', async function({page, server}) {
|
||||
expect(coverage[1].url).toContain('/jscoverage/script2.js');
|
||||
});
|
||||
|
||||
it('should report scripts across navigations when disabled', async function({page, server}) {
|
||||
await page.coverage.startJSCoverage({resetOnNavigation: false});
|
||||
it('should report scripts across navigations when disabled', async function({ page, server }) {
|
||||
await page.coverage.startJSCoverage({ resetOnNavigation: false });
|
||||
await page.goto(server.PREFIX + '/jscoverage/multiple.html');
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const coverage = await page.coverage.stopJSCoverage();
|
||||
expect(coverage.length).toBe(2);
|
||||
});
|
||||
|
||||
it('should NOT report scripts across navigations when enabled', async function({page, server}) {
|
||||
it('should NOT report scripts across navigations when enabled', async function({ page, server }) {
|
||||
await page.coverage.startJSCoverage(); // Enabled by default.
|
||||
await page.goto(server.PREFIX + '/jscoverage/multiple.html');
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -76,7 +76,7 @@ it('should NOT report scripts across navigations when enabled', async function({
|
||||
expect(coverage.length).toBe(0);
|
||||
});
|
||||
|
||||
it('should not hang when there is a debugger statement', async function({page, server}) {
|
||||
it('should not hang when there is a debugger statement', async function({ page, server }) {
|
||||
await page.coverage.startJSCoverage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.evaluate(() => {
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
import { playwrightTest as it, expect } from '../config/browserTest';
|
||||
|
||||
it('should throw with remote-debugging-pipe argument', async ({browserType, browserOptions, mode}) => {
|
||||
it('should throw with remote-debugging-pipe argument', async ({ browserType, browserOptions, mode }) => {
|
||||
it.skip(mode !== 'default');
|
||||
|
||||
const options = Object.assign({}, browserOptions);
|
||||
@ -25,7 +25,7 @@ it('should throw with remote-debugging-pipe argument', async ({browserType, brow
|
||||
expect(error.message).toContain('Playwright manages remote debugging connection itself');
|
||||
});
|
||||
|
||||
it('should not throw with remote-debugging-port argument', async ({browserType, browserOptions, mode}) => {
|
||||
it('should not throw with remote-debugging-port argument', async ({ browserType, browserOptions, mode }) => {
|
||||
it.skip(mode !== 'default');
|
||||
|
||||
const options = Object.assign({}, browserOptions);
|
||||
@ -34,7 +34,7 @@ it('should not throw with remote-debugging-port argument', async ({browserType,
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should open devtools when "devtools: true" option is given', async ({browserType, browserOptions, mode, platform, channel}) => {
|
||||
it('should open devtools when "devtools: true" option is given', async ({ browserType, browserOptions, mode, platform, channel }) => {
|
||||
it.skip(mode !== 'default' || platform === 'win32' || !!channel);
|
||||
|
||||
let devtoolsCallback;
|
||||
@ -43,7 +43,7 @@ it('should open devtools when "devtools: true" option is given', async ({browser
|
||||
if (parsed.method === 'getPreferences')
|
||||
devtoolsCallback();
|
||||
};
|
||||
const browser = await browserType.launch({...browserOptions, headless: false, devtools: true, __testHookForDevTools} as any);
|
||||
const browser = await browserType.launch({ ...browserOptions, headless: false, devtools: true, __testHookForDevTools } as any);
|
||||
const context = await browser.newContext();
|
||||
await Promise.all([
|
||||
devtoolsPromise,
|
||||
@ -52,10 +52,10 @@ it('should open devtools when "devtools: true" option is given', async ({browser
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should return background pages', async ({browserType, browserOptions, createUserDataDir, asset}) => {
|
||||
it('should return background pages', async ({ browserType, browserOptions, createUserDataDir, asset }) => {
|
||||
const userDataDir = await createUserDataDir();
|
||||
const extensionPath = asset('simple-extension');
|
||||
const extensionOptions = {...browserOptions,
|
||||
const extensionOptions = { ...browserOptions,
|
||||
headless: false,
|
||||
args: [
|
||||
`--disable-extensions-except=${extensionPath}`,
|
||||
@ -75,10 +75,10 @@ it('should return background pages', async ({browserType, browserOptions, create
|
||||
expect(context.backgroundPages().length).toBe(0);
|
||||
});
|
||||
|
||||
it('should return background pages when recording video', async ({browserType, browserOptions, createUserDataDir, asset}, testInfo) => {
|
||||
it('should return background pages when recording video', async ({ browserType, browserOptions, createUserDataDir, asset }, testInfo) => {
|
||||
const userDataDir = await createUserDataDir();
|
||||
const extensionPath = asset('simple-extension');
|
||||
const extensionOptions = {...browserOptions,
|
||||
const extensionOptions = { ...browserOptions,
|
||||
headless: false,
|
||||
args: [
|
||||
`--disable-extensions-except=${extensionPath}`,
|
||||
@ -99,11 +99,11 @@ it('should return background pages when recording video', async ({browserType, b
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should not create pages automatically', async ({browserType, browserOptions}) => {
|
||||
it('should not create pages automatically', async ({ browserType, browserOptions }) => {
|
||||
const browser = await browserType.launch(browserOptions);
|
||||
const browserSession = await browser.newBrowserCDPSession();
|
||||
const targets = [];
|
||||
browserSession.on('Target.targetCreated', async ({targetInfo}) => {
|
||||
browserSession.on('Target.targetCreated', async ({ targetInfo }) => {
|
||||
if (targetInfo.type !== 'browser')
|
||||
targets.push(targetInfo);
|
||||
});
|
||||
|
@ -18,14 +18,14 @@ import { contextTest as it, expect } from '../config/browserTest';
|
||||
|
||||
it.use({ args: ['--site-per-process'] });
|
||||
|
||||
it('should report oopif frames', async function({page, browser, server}) {
|
||||
it('should report oopif frames', async function({ page, browser, server }) {
|
||||
await page.goto(server.PREFIX + '/dynamic-oopif.html');
|
||||
expect(await countOOPIFs(browser)).toBe(1);
|
||||
expect(page.frames().length).toBe(2);
|
||||
expect(await page.frames()[1].evaluate(() => '' + location.href)).toBe(server.CROSS_PROCESS_PREFIX + '/grid.html');
|
||||
});
|
||||
|
||||
it('should handle oopif detach', async function({page, browser, server}) {
|
||||
it('should handle oopif detach', async function({ page, browser, server }) {
|
||||
await page.goto(server.PREFIX + '/dynamic-oopif.html');
|
||||
expect(await countOOPIFs(browser)).toBe(1);
|
||||
expect(page.frames().length).toBe(2);
|
||||
@ -38,7 +38,7 @@ it('should handle oopif detach', async function({page, browser, server}) {
|
||||
expect(detachedFrame).toBe(frame);
|
||||
});
|
||||
|
||||
it('should handle remote -> local -> remote transitions', async function({page, browser, server}) {
|
||||
it('should handle remote -> local -> remote transitions', async function({ page, browser, server }) {
|
||||
await page.goto(server.PREFIX + '/dynamic-oopif.html');
|
||||
expect(page.frames().length).toBe(2);
|
||||
expect(await countOOPIFs(browser)).toBe(1);
|
||||
@ -57,10 +57,10 @@ it('should handle remote -> local -> remote transitions', async function({page,
|
||||
expect(await countOOPIFs(browser)).toBe(1);
|
||||
});
|
||||
|
||||
it('should get the proper viewport', async ({page, browser, server}) => {
|
||||
it('should get the proper viewport', async ({ page, browser, server }) => {
|
||||
it.fixme();
|
||||
|
||||
expect(page.viewportSize()).toEqual({width: 1280, height: 720});
|
||||
expect(page.viewportSize()).toEqual({ width: 1280, height: 720 });
|
||||
await page.goto(server.PREFIX + '/dynamic-oopif.html');
|
||||
expect(page.frames().length).toBe(2);
|
||||
expect(await countOOPIFs(browser)).toBe(1);
|
||||
@ -70,7 +70,7 @@ it('should get the proper viewport', async ({page, browser, server}) => {
|
||||
expect(await oopif.evaluate(() => matchMedia('(device-width: 1280px)').matches)).toBe(true);
|
||||
expect(await oopif.evaluate(() => matchMedia('(device-height: 720px)').matches)).toBe(true);
|
||||
expect(await oopif.evaluate(() => 'ontouchstart' in window)).toBe(false);
|
||||
await page.setViewportSize({width: 123, height: 456});
|
||||
await page.setViewportSize({ width: 123, height: 456 });
|
||||
expect(await oopif.evaluate(() => screen.width)).toBe(123);
|
||||
expect(await oopif.evaluate(() => screen.height)).toBe(456);
|
||||
expect(await oopif.evaluate(() => matchMedia('(device-width: 123px)').matches)).toBe(true);
|
||||
@ -78,7 +78,7 @@ it('should get the proper viewport', async ({page, browser, server}) => {
|
||||
expect(await oopif.evaluate(() => 'ontouchstart' in window)).toBe(false);
|
||||
});
|
||||
|
||||
it('should expose function', async ({page, browser, server}) => {
|
||||
it('should expose function', async ({ page, browser, server }) => {
|
||||
await page.goto(server.PREFIX + '/dynamic-oopif.html');
|
||||
expect(page.frames().length).toBe(2);
|
||||
expect(await countOOPIFs(browser)).toBe(1);
|
||||
@ -90,7 +90,7 @@ it('should expose function', async ({page, browser, server}) => {
|
||||
expect(result).toBe(36);
|
||||
});
|
||||
|
||||
it('should emulate media', async ({page, browser, server}) => {
|
||||
it('should emulate media', async ({ page, browser, server }) => {
|
||||
await page.goto(server.PREFIX + '/dynamic-oopif.html');
|
||||
expect(page.frames().length).toBe(2);
|
||||
expect(await countOOPIFs(browser)).toBe(1);
|
||||
@ -100,7 +100,7 @@ it('should emulate media', async ({page, browser, server}) => {
|
||||
expect(await oopif.evaluate(() => matchMedia('(prefers-color-scheme: dark)').matches)).toBe(true);
|
||||
});
|
||||
|
||||
it('should emulate offline', async ({page, browser, server}) => {
|
||||
it('should emulate offline', async ({ page, browser, server }) => {
|
||||
await page.goto(server.PREFIX + '/dynamic-oopif.html');
|
||||
expect(page.frames().length).toBe(2);
|
||||
expect(await countOOPIFs(browser)).toBe(1);
|
||||
@ -110,7 +110,7 @@ it('should emulate offline', async ({page, browser, server}) => {
|
||||
expect(await oopif.evaluate(() => navigator.onLine)).toBe(false);
|
||||
});
|
||||
|
||||
it('should support context options', async ({browser, server, playwright}) => {
|
||||
it('should support context options', async ({ browser, server, playwright }) => {
|
||||
const iPhone = playwright.devices['iPhone 6'];
|
||||
const context = await browser.newContext({ ...iPhone, timezoneId: 'America/Jamaica', locale: 'fr-CH', userAgent: 'UA' });
|
||||
const page = await context.newPage();
|
||||
@ -132,7 +132,7 @@ it('should support context options', async ({browser, server, playwright}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should respect route', async ({page, browser, server}) => {
|
||||
it('should respect route', async ({ page, browser, server }) => {
|
||||
let intercepted = false;
|
||||
await page.route('**/digits/0.png', route => {
|
||||
intercepted = true;
|
||||
@ -144,21 +144,21 @@ it('should respect route', async ({page, browser, server}) => {
|
||||
expect(intercepted).toBe(true);
|
||||
});
|
||||
|
||||
it('should take screenshot', async ({page, browser, server}) => {
|
||||
await page.setViewportSize({width: 500, height: 500});
|
||||
it('should take screenshot', async ({ page, browser, server }) => {
|
||||
await page.setViewportSize({ width: 500, height: 500 });
|
||||
await page.goto(server.PREFIX + '/dynamic-oopif.html');
|
||||
expect(page.frames().length).toBe(2);
|
||||
expect(await countOOPIFs(browser)).toBe(1);
|
||||
expect(await page.screenshot()).toMatchSnapshot('screenshot-oopif.png', { threshold: 0.3 });
|
||||
});
|
||||
|
||||
it('should load oopif iframes with subresources and route', async function({page, browser, server}) {
|
||||
it('should load oopif iframes with subresources and route', async function({ page, browser, server }) {
|
||||
await page.route('**/*', route => route.continue());
|
||||
await page.goto(server.PREFIX + '/dynamic-oopif.html');
|
||||
expect(await countOOPIFs(browser)).toBe(1);
|
||||
});
|
||||
|
||||
it('should report main requests', async function({page, browser, server}) {
|
||||
it('should report main requests', async function({ page, browser, server }) {
|
||||
const requestFrames = [];
|
||||
page.on('request', r => requestFrames.push(r.frame()));
|
||||
const finishedFrames = [];
|
||||
@ -196,7 +196,7 @@ it('should report main requests', async function({page, browser, server}) {
|
||||
expect(finishedFrames[2]).toBe(grandChild);
|
||||
});
|
||||
|
||||
it('should support exposeFunction', async function({page, browser, server}) {
|
||||
it('should support exposeFunction', async function({ page, browser, server }) {
|
||||
await page.context().exposeFunction('dec', a => a - 1);
|
||||
await page.exposeFunction('inc', a => a + 1);
|
||||
await page.goto(server.PREFIX + '/dynamic-oopif.html');
|
||||
@ -208,7 +208,7 @@ it('should support exposeFunction', async function({page, browser, server}) {
|
||||
expect(await page.frames()[1].evaluate(() => window['dec'](4))).toBe(3);
|
||||
});
|
||||
|
||||
it('should support addInitScript', async function({page, browser, server}) {
|
||||
it('should support addInitScript', async function({ page, browser, server }) {
|
||||
await page.context().addInitScript(() => window['bar'] = 17);
|
||||
await page.addInitScript(() => window['foo'] = 42);
|
||||
await page.goto(server.PREFIX + '/dynamic-oopif.html');
|
||||
@ -220,21 +220,21 @@ it('should support addInitScript', async function({page, browser, server}) {
|
||||
expect(await page.frames()[1].evaluate(() => window['bar'])).toBe(17);
|
||||
});
|
||||
// @see https://github.com/microsoft/playwright/issues/1240
|
||||
it('should click a button when it overlays oopif', async function({page, browser, server}) {
|
||||
it('should click a button when it overlays oopif', async function({ page, browser, server }) {
|
||||
await page.goto(server.PREFIX + '/button-overlay-oopif.html');
|
||||
expect(await countOOPIFs(browser)).toBe(1);
|
||||
await page.click('button');
|
||||
expect(await page.evaluate(() => window['BUTTON_CLICKED'])).toBe(true);
|
||||
});
|
||||
|
||||
it('should report google.com frame with headed', async ({browserType, browserOptions, server}) => {
|
||||
it('should report google.com frame with headed', async ({ browserType, browserOptions, server }) => {
|
||||
// @see https://github.com/GoogleChrome/puppeteer/issues/2548
|
||||
// https://google.com is isolated by default in Chromium embedder.
|
||||
const browser = await browserType.launch({...browserOptions, headless: false});
|
||||
const browser = await browserType.launch({ ...browserOptions, headless: false });
|
||||
const page = await browser.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.route('**/*', route => {
|
||||
route.fulfill({body: 'YO, GOOGLE.COM'});
|
||||
route.fulfill({ body: 'YO, GOOGLE.COM' });
|
||||
});
|
||||
await page.evaluate(() => {
|
||||
const frame = document.createElement('iframe');
|
||||
@ -252,7 +252,7 @@ it('should report google.com frame with headed', async ({browserType, browserOpt
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('ElementHandle.boundingBox() should work', async function({page, browser, server}) {
|
||||
it('ElementHandle.boundingBox() should work', async function({ page, browser, server }) {
|
||||
await page.goto(server.PREFIX + '/dynamic-oopif.html');
|
||||
await page.$eval('iframe', iframe => {
|
||||
iframe.style.width = '500px';
|
||||
@ -275,7 +275,7 @@ it('ElementHandle.boundingBox() should work', async function({page, browser, ser
|
||||
expect(await handle2.boundingBox()).toEqual({ x: 100 + 42, y: 50 + 17, width: 50, height: 50 });
|
||||
});
|
||||
|
||||
it('should click', async function({page, browser, server}) {
|
||||
it('should click', async function({ page, browser, server }) {
|
||||
await page.goto(server.PREFIX + '/dynamic-oopif.html');
|
||||
await page.$eval('iframe', iframe => {
|
||||
iframe.style.width = '500px';
|
||||
@ -292,7 +292,7 @@ it('should click', async function({page, browser, server}) {
|
||||
expect(await handle1.evaluate(() => window['_clicked'])).toBe(true);
|
||||
});
|
||||
|
||||
it('should allow cdp sessions on oopifs', async function({page, browser, server}) {
|
||||
it('should allow cdp sessions on oopifs', async function({ page, browser, server }) {
|
||||
await page.goto(server.PREFIX + '/dynamic-oopif.html');
|
||||
expect(await countOOPIFs(browser)).toBe(1);
|
||||
expect(page.frames().length).toBe(2);
|
||||
@ -303,14 +303,14 @@ it('should allow cdp sessions on oopifs', async function({page, browser, server}
|
||||
expect(JSON.stringify(parent)).not.toContain('./digits/1.png');
|
||||
|
||||
const oopifCDP = await page.context().newCDPSession(page.frames()[1]);
|
||||
const oopif = await oopifCDP.send('DOM.getDocument', { pierce: true, depth: -1});
|
||||
const oopif = await oopifCDP.send('DOM.getDocument', { pierce: true, depth: -1 });
|
||||
expect(JSON.stringify(oopif)).toContain('./digits/1.png');
|
||||
});
|
||||
|
||||
async function countOOPIFs(browser) {
|
||||
const browserSession = await browser.newBrowserCDPSession();
|
||||
const oopifs = [];
|
||||
browserSession.on('Target.targetCreated', async ({targetInfo}) => {
|
||||
browserSession.on('Target.targetCreated', async ({ targetInfo }) => {
|
||||
if (targetInfo.type === 'iframe')
|
||||
oopifs.push(targetInfo);
|
||||
});
|
||||
|
@ -17,7 +17,7 @@
|
||||
import { contextTest as it, expect } from '../config/browserTest';
|
||||
import { browserTest } from '../config/browserTest';
|
||||
|
||||
it('should work', async function({page}) {
|
||||
it('should work', async function({ page }) {
|
||||
const client = await page.context().newCDPSession(page);
|
||||
|
||||
await Promise.all([
|
||||
@ -28,7 +28,7 @@ it('should work', async function({page}) {
|
||||
expect(foo).toBe('bar');
|
||||
});
|
||||
|
||||
it('should send events', async function({page, server}) {
|
||||
it('should send events', async function({ page, server }) {
|
||||
const client = await page.context().newCDPSession(page);
|
||||
await client.send('Network.enable');
|
||||
const events = [];
|
||||
@ -37,7 +37,7 @@ it('should send events', async function({page, server}) {
|
||||
expect(events.length).toBe(1);
|
||||
});
|
||||
|
||||
it('should only accept a page or frame', async function({page}) {
|
||||
it('should only accept a page or frame', async function({ page }) {
|
||||
// @ts-expect-error newCDPSession expects a Page or Frame
|
||||
const error = await page.context().newCDPSession(page.context()).catch(e => e);
|
||||
expect(error.message).toContain('page: expected Page or Frame');
|
||||
@ -48,7 +48,7 @@ it('should only accept a page or frame', async function({page}) {
|
||||
expect(errorAlt.message).toContain('page: expected Page or Frame');
|
||||
});
|
||||
|
||||
it('should enable and disable domains independently', async function({page}) {
|
||||
it('should enable and disable domains independently', async function({ page }) {
|
||||
const client = await page.context().newCDPSession(page);
|
||||
await client.send('Runtime.enable');
|
||||
await client.send('Debugger.enable');
|
||||
@ -66,22 +66,22 @@ it('should enable and disable domains independently', async function({page}) {
|
||||
]);
|
||||
});
|
||||
|
||||
it('should be able to detach session', async function({page}) {
|
||||
it('should be able to detach session', async function({ page }) {
|
||||
const client = await page.context().newCDPSession(page);
|
||||
await client.send('Runtime.enable');
|
||||
const evalResponse = await client.send('Runtime.evaluate', {expression: '1 + 2', returnByValue: true});
|
||||
const evalResponse = await client.send('Runtime.evaluate', { expression: '1 + 2', returnByValue: true });
|
||||
expect(evalResponse.result.value).toBe(3);
|
||||
await client.detach();
|
||||
let error = null;
|
||||
try {
|
||||
await client.send('Runtime.evaluate', {expression: '3 + 1', returnByValue: true});
|
||||
await client.send('Runtime.evaluate', { expression: '3 + 1', returnByValue: true });
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
expect(error.message).toContain('Target page, context or browser has been closed');
|
||||
});
|
||||
|
||||
it('should throw nice errors', async function({page}) {
|
||||
it('should throw nice errors', async function({ page }) {
|
||||
const client = await page.context().newCDPSession(page);
|
||||
const error = await theSourceOfTheProblems().catch(error => error);
|
||||
expect(error.stack).toContain('theSourceOfTheProblems');
|
||||
@ -93,7 +93,7 @@ it('should throw nice errors', async function({page}) {
|
||||
}
|
||||
});
|
||||
|
||||
it('should work with main frame', async function({page}) {
|
||||
it('should work with main frame', async function({ page }) {
|
||||
const client = await page.context().newCDPSession(page.mainFrame());
|
||||
|
||||
await Promise.all([
|
||||
@ -104,7 +104,7 @@ it('should work with main frame', async function({page}) {
|
||||
expect(foo).toBe('bar');
|
||||
});
|
||||
|
||||
it('should throw if target is part of main', async function({server, page}){
|
||||
it('should throw if target is part of main', async function({ server, page }){
|
||||
await page.goto(server.PREFIX + '/frames/one-frame.html');
|
||||
expect(page.frames()[0].url()).toContain('/frames/one-frame.html');
|
||||
expect(page.frames()[1].url()).toContain('/frames/frame.html');
|
||||
@ -113,7 +113,7 @@ it('should throw if target is part of main', async function({server, page}){
|
||||
expect(error.message).toContain(`This frame does not have a separate CDP session, it is a part of the parent frame's session`);
|
||||
});
|
||||
|
||||
browserTest('should not break page.close()', async function({browser}) {
|
||||
browserTest('should not break page.close()', async function({ browser }) {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
const session = await page.context().newCDPSession(page);
|
||||
@ -122,7 +122,7 @@ browserTest('should not break page.close()', async function({browser}) {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
browserTest('should detach when page closes', async function({browser}) {
|
||||
browserTest('should detach when page closes', async function({ browser }) {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
const session = await context.newCDPSession(page);
|
||||
@ -133,7 +133,7 @@ browserTest('should detach when page closes', async function({browser}) {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
browserTest('should work with newBrowserCDPSession', async function({browser}) {
|
||||
browserTest('should work with newBrowserCDPSession', async function({ browser }) {
|
||||
const session = await browser.newBrowserCDPSession();
|
||||
|
||||
const version = await session.send('Browser.getVersion');
|
||||
|
@ -18,30 +18,30 @@ import { browserTest as it, expect } from '../config/browserTest';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
it('should output a trace', async ({browser, server}, testInfo) => {
|
||||
it('should output a trace', async ({ browser, server }, testInfo) => {
|
||||
const page = await browser.newPage();
|
||||
const outputTraceFile = testInfo.outputPath(path.join(`trace.json`));
|
||||
await browser.startTracing(page, {screenshots: true, path: outputTraceFile});
|
||||
await browser.startTracing(page, { screenshots: true, path: outputTraceFile });
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
await browser.stopTracing();
|
||||
expect(fs.existsSync(outputTraceFile)).toBe(true);
|
||||
await page.close();
|
||||
});
|
||||
|
||||
it('should create directories as needed', async ({browser, server}, testInfo) => {
|
||||
it('should create directories as needed', async ({ browser, server }, testInfo) => {
|
||||
const page = await browser.newPage();
|
||||
const filePath = testInfo.outputPath(path.join('these', 'are', 'directories', 'trace.json'));
|
||||
await browser.startTracing(page, {screenshots: true, path: filePath});
|
||||
await browser.startTracing(page, { screenshots: true, path: filePath });
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
await browser.stopTracing();
|
||||
expect(fs.existsSync(filePath)).toBe(true);
|
||||
await page.close();
|
||||
});
|
||||
|
||||
it('should run with custom categories if provided', async ({browser}, testInfo) => {
|
||||
it('should run with custom categories if provided', async ({ browser }, testInfo) => {
|
||||
const page = await browser.newPage();
|
||||
const outputTraceFile = testInfo.outputPath(path.join(`trace.json`));
|
||||
await browser.startTracing(page, {path: outputTraceFile, categories: ['disabled-by-default-v8.cpu_profiler.hires']});
|
||||
await browser.startTracing(page, { path: outputTraceFile, categories: ['disabled-by-default-v8.cpu_profiler.hires'] });
|
||||
await browser.stopTracing();
|
||||
|
||||
const traceJson = JSON.parse(fs.readFileSync(outputTraceFile).toString());
|
||||
@ -49,23 +49,23 @@ it('should run with custom categories if provided', async ({browser}, testInfo)
|
||||
await page.close();
|
||||
});
|
||||
|
||||
it('should throw if tracing on two pages', async ({browser}, testInfo) => {
|
||||
it('should throw if tracing on two pages', async ({ browser }, testInfo) => {
|
||||
const page = await browser.newPage();
|
||||
const outputTraceFile = testInfo.outputPath(path.join(`trace.json`));
|
||||
await browser.startTracing(page, {path: outputTraceFile});
|
||||
await browser.startTracing(page, { path: outputTraceFile });
|
||||
const newPage = await browser.newPage();
|
||||
let error = null;
|
||||
await browser.startTracing(newPage, {path: outputTraceFile}).catch(e => error = e);
|
||||
await browser.startTracing(newPage, { path: outputTraceFile }).catch(e => error = e);
|
||||
await newPage.close();
|
||||
expect(error).toBeTruthy();
|
||||
await browser.stopTracing();
|
||||
await page.close();
|
||||
});
|
||||
|
||||
it('should return a buffer', async ({browser, server}, testInfo) => {
|
||||
it('should return a buffer', async ({ browser, server }, testInfo) => {
|
||||
const page = await browser.newPage();
|
||||
const outputTraceFile = testInfo.outputPath(path.join(`trace.json`));
|
||||
await browser.startTracing(page, {screenshots: true, path: outputTraceFile});
|
||||
await browser.startTracing(page, { screenshots: true, path: outputTraceFile });
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
const trace = await browser.stopTracing();
|
||||
const buf = fs.readFileSync(outputTraceFile);
|
||||
@ -73,7 +73,7 @@ it('should return a buffer', async ({browser, server}, testInfo) => {
|
||||
await page.close();
|
||||
});
|
||||
|
||||
it('should work without options', async ({browser, server}) => {
|
||||
it('should work without options', async ({ browser, server }) => {
|
||||
const page = await browser.newPage();
|
||||
await browser.startTracing(page);
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
@ -82,9 +82,9 @@ it('should work without options', async ({browser, server}) => {
|
||||
await page.close();
|
||||
});
|
||||
|
||||
it('should support a buffer without a path', async ({browser, server}) => {
|
||||
it('should support a buffer without a path', async ({ browser, server }) => {
|
||||
const page = await browser.newPage();
|
||||
await browser.startTracing(page, {screenshots: true});
|
||||
await browser.startTracing(page, { screenshots: true });
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
const trace = await browser.stopTracing();
|
||||
expect(trace.toString()).toContain('screenshot');
|
||||
|
@ -76,7 +76,7 @@ class ServiceMode {
|
||||
});
|
||||
});
|
||||
this._serviceProcess.on('exit', this._onExit);
|
||||
this._client = await PlaywrightClient.connect({wsEndpoint: `ws://localhost:${port}/ws`});
|
||||
this._client = await PlaywrightClient.connect({ wsEndpoint: `ws://localhost:${port}/ws` });
|
||||
return this._client.playwright();
|
||||
}
|
||||
|
||||
|
@ -19,8 +19,8 @@ import { playwrightTest as it, expect } from './config/browserTest';
|
||||
import { verifyViewport } from './config/utils';
|
||||
import fs from 'fs';
|
||||
|
||||
it('context.cookies() should work', async ({server, launchPersistent, browserName}) => {
|
||||
const {page} = await launchPersistent();
|
||||
it('context.cookies() should work', async ({ server, launchPersistent, browserName }) => {
|
||||
const { page } = await launchPersistent();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const documentCookie = await page.evaluate(() => {
|
||||
document.cookie = 'username=John Doe';
|
||||
@ -39,8 +39,8 @@ it('context.cookies() should work', async ({server, launchPersistent, browserNam
|
||||
}]);
|
||||
});
|
||||
|
||||
it('context.addCookies() should work', async ({server, launchPersistent, browserName, isWindows}) => {
|
||||
const {page} = await launchPersistent();
|
||||
it('context.addCookies() should work', async ({ server, launchPersistent, browserName, isWindows }) => {
|
||||
const { page } = await launchPersistent();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.context().addCookies([{
|
||||
url: server.EMPTY_PAGE,
|
||||
@ -61,8 +61,8 @@ it('context.addCookies() should work', async ({server, launchPersistent, browser
|
||||
}]);
|
||||
});
|
||||
|
||||
it('context.clearCookies() should work', async ({server, launchPersistent}) => {
|
||||
const {page} = await launchPersistent();
|
||||
it('context.clearCookies() should work', async ({ server, launchPersistent }) => {
|
||||
const { page } = await launchPersistent();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.context().addCookies([{
|
||||
url: server.EMPTY_PAGE,
|
||||
@ -80,8 +80,8 @@ it('context.clearCookies() should work', async ({server, launchPersistent}) => {
|
||||
expect(await page.evaluate('document.cookie')).toBe('');
|
||||
});
|
||||
|
||||
it('should(not) block third party cookies', async ({server, launchPersistent, browserName}) => {
|
||||
const {page, context} = await launchPersistent();
|
||||
it('should(not) block third party cookies', async ({ server, launchPersistent, browserName }) => {
|
||||
const { page, context } = await launchPersistent();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.evaluate(src => {
|
||||
let fulfill;
|
||||
@ -118,20 +118,20 @@ it('should(not) block third party cookies', async ({server, launchPersistent, br
|
||||
}
|
||||
});
|
||||
|
||||
it('should support viewport option', async ({launchPersistent}) => {
|
||||
const {page, context} = await launchPersistent({viewport: { width: 456, height: 789 }});
|
||||
it('should support viewport option', async ({ launchPersistent }) => {
|
||||
const { page, context } = await launchPersistent({ viewport: { width: 456, height: 789 } });
|
||||
await verifyViewport(page, 456, 789);
|
||||
const page2 = await context.newPage();
|
||||
await verifyViewport(page2, 456, 789);
|
||||
});
|
||||
|
||||
it('should support deviceScaleFactor option', async ({launchPersistent}) => {
|
||||
const {page} = await launchPersistent({deviceScaleFactor: 3});
|
||||
it('should support deviceScaleFactor option', async ({ launchPersistent }) => {
|
||||
const { page } = await launchPersistent({ deviceScaleFactor: 3 });
|
||||
expect(await page.evaluate('window.devicePixelRatio')).toBe(3);
|
||||
});
|
||||
|
||||
it('should support userAgent option', async ({server, launchPersistent}) => {
|
||||
const {page} = await launchPersistent({userAgent: 'foobar'});
|
||||
it('should support userAgent option', async ({ server, launchPersistent }) => {
|
||||
const { page } = await launchPersistent({ userAgent: 'foobar' });
|
||||
expect(await page.evaluate(() => navigator.userAgent)).toBe('foobar');
|
||||
const [request] = await Promise.all([
|
||||
server.waitForRequest('/empty.html'),
|
||||
@ -140,15 +140,15 @@ it('should support userAgent option', async ({server, launchPersistent}) => {
|
||||
expect(request.headers['user-agent']).toBe('foobar');
|
||||
});
|
||||
|
||||
it('should support bypassCSP option', async ({server, launchPersistent}) => {
|
||||
const {page} = await launchPersistent({bypassCSP: true});
|
||||
it('should support bypassCSP option', async ({ server, launchPersistent }) => {
|
||||
const { page } = await launchPersistent({ bypassCSP: true });
|
||||
await page.goto(server.PREFIX + '/csp.html');
|
||||
await page.addScriptTag({content: 'window["__injected"] = 42;'});
|
||||
await page.addScriptTag({ content: 'window["__injected"] = 42;' });
|
||||
expect(await page.evaluate('__injected')).toBe(42);
|
||||
});
|
||||
|
||||
it('should support javascriptEnabled option', async ({launchPersistent, browserName}) => {
|
||||
const {page} = await launchPersistent({javaScriptEnabled: false});
|
||||
it('should support javascriptEnabled option', async ({ launchPersistent, browserName }) => {
|
||||
const { page } = await launchPersistent({ javaScriptEnabled: false });
|
||||
await page.goto('data:text/html, <script>var something = "forbidden"</script>');
|
||||
let error = null;
|
||||
await page.evaluate('something').catch(e => error = e);
|
||||
@ -158,23 +158,23 @@ it('should support javascriptEnabled option', async ({launchPersistent, browserN
|
||||
expect(error.message).toContain('something is not defined');
|
||||
});
|
||||
|
||||
it('should support httpCredentials option', async ({server, launchPersistent}) => {
|
||||
const {page} = await launchPersistent({httpCredentials: { username: 'user', password: 'pass' }});
|
||||
it('should support httpCredentials option', async ({ server, launchPersistent }) => {
|
||||
const { page } = await launchPersistent({ httpCredentials: { username: 'user', password: 'pass' } });
|
||||
server.setAuth('/playground.html', 'user', 'pass');
|
||||
const response = await page.goto(server.PREFIX + '/playground.html');
|
||||
expect(response.status()).toBe(200);
|
||||
});
|
||||
|
||||
it('should support offline option', async ({server, launchPersistent}) => {
|
||||
const {page} = await launchPersistent({offline: true});
|
||||
it('should support offline option', async ({ server, launchPersistent }) => {
|
||||
const { page } = await launchPersistent({ offline: true });
|
||||
const error = await page.goto(server.EMPTY_PAGE).catch(e => e);
|
||||
expect(error).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should support acceptDownloads option', async ({server, launchPersistent}) => {
|
||||
it('should support acceptDownloads option', async ({ server, launchPersistent }) => {
|
||||
it.skip(true, 'Unskip once we support downloads in persistent context.');
|
||||
|
||||
const {page} = await launchPersistent({acceptDownloads: true});
|
||||
const { page } = await launchPersistent({ acceptDownloads: true });
|
||||
server.setRoute('/download', (req, res) => {
|
||||
res.setHeader('Content-Type', 'application/octet-stream');
|
||||
res.setHeader('Content-Disposition', 'attachment');
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user