mirror of
				https://github.com/microsoft/playwright.git
				synced 2025-06-26 21:40:17 +00:00 
			
		
		
		
	chore: implement jsHandle._objectCount in chromium (#22127)
This commit is contained in:
		
							parent
							
								
									5223c1ba39
								
							
						
					
					
						commit
						0d9ec60dc7
					
				@ -67,6 +67,13 @@ export class JSHandle<T = any> extends ChannelOwner<channels.JSHandleChannel> im
 | 
			
		||||
    return await this._channel.dispose();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async _objectCount() {
 | 
			
		||||
    return this._wrapApiCall(async () => {
 | 
			
		||||
      const { count } = await this._channel.objectCount();
 | 
			
		||||
      return count;
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  override toString(): string {
 | 
			
		||||
    return this._preview;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -1703,6 +1703,12 @@ scheme.JSHandleJsonValueResult = tObject({
 | 
			
		||||
  value: tType('SerializedValue'),
 | 
			
		||||
});
 | 
			
		||||
scheme.ElementHandleJsonValueResult = tType('JSHandleJsonValueResult');
 | 
			
		||||
scheme.JSHandleObjectCountParams = tOptional(tObject({}));
 | 
			
		||||
scheme.ElementHandleObjectCountParams = tType('JSHandleObjectCountParams');
 | 
			
		||||
scheme.JSHandleObjectCountResult = tObject({
 | 
			
		||||
  count: tNumber,
 | 
			
		||||
});
 | 
			
		||||
scheme.ElementHandleObjectCountResult = tType('JSHandleObjectCountResult');
 | 
			
		||||
scheme.ElementHandleInitializer = tObject({
 | 
			
		||||
  preview: tString,
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
@ -102,6 +102,14 @@ export class CRExecutionContext implements js.ExecutionContextDelegate {
 | 
			
		||||
  async releaseHandle(objectId: js.ObjectId): Promise<void> {
 | 
			
		||||
    await releaseObject(this._client, objectId);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async objectCount(objectId: js.ObjectId): Promise<number> {
 | 
			
		||||
    const result = await this._client.send('Runtime.queryObjects', {
 | 
			
		||||
      prototypeObjectId: objectId
 | 
			
		||||
    });
 | 
			
		||||
    const match = result.objects.description!.match(/Array\((\d+)\)/)!;
 | 
			
		||||
    return +match[1];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function rewriteError(error: Error): Protocol.Runtime.evaluateReturnValue {
 | 
			
		||||
 | 
			
		||||
@ -61,6 +61,10 @@ export class JSHandleDispatcher extends Dispatcher<js.JSHandle, channels.JSHandl
 | 
			
		||||
    return { value: serializeResult(await this._object.jsonValue()) };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async objectCount(params?: channels.JSHandleObjectCountParams | undefined): Promise<channels.JSHandleObjectCountResult> {
 | 
			
		||||
    return { count: await this._object.objectCount() };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async dispose() {
 | 
			
		||||
    await this._object.dispose();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -98,6 +98,10 @@ export class FFExecutionContext implements js.ExecutionContextDelegate {
 | 
			
		||||
      objectId
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  objectCount(objectId: js.ObjectId): Promise<number> {
 | 
			
		||||
    throw new Error('Method not implemented in Firefox.');
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function checkException(exceptionDetails?: Protocol.Runtime.ExceptionDetails) {
 | 
			
		||||
 | 
			
		||||
@ -57,6 +57,7 @@ export interface ExecutionContextDelegate {
 | 
			
		||||
  getProperties(context: ExecutionContext, objectId: ObjectId): Promise<Map<string, JSHandle>>;
 | 
			
		||||
  createHandle(context: ExecutionContext, remoteObject: RemoteObject): JSHandle;
 | 
			
		||||
  releaseHandle(objectId: ObjectId): Promise<void>;
 | 
			
		||||
  objectCount(objectId: ObjectId): Promise<number>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class ExecutionContext extends SdkObject {
 | 
			
		||||
@ -126,6 +127,10 @@ export class ExecutionContext extends SdkObject {
 | 
			
		||||
    return this._utilityScriptPromise;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async objectCount(objectId: ObjectId): Promise<number> {
 | 
			
		||||
    return this._delegate.objectCount(objectId);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async doSlowMo() {
 | 
			
		||||
    // overridden in FrameExecutionContext
 | 
			
		||||
  }
 | 
			
		||||
@ -227,6 +232,13 @@ export class JSHandle<T = any> extends SdkObject {
 | 
			
		||||
    if (this._previewCallback)
 | 
			
		||||
      this._previewCallback(preview);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  async objectCount(): Promise<number> {
 | 
			
		||||
    if (!this._objectId)
 | 
			
		||||
      throw new Error('Can only count objects for a handle that points to the constructor prototype');
 | 
			
		||||
    return this._context.objectCount(this._objectId);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export async function evaluate(context: ExecutionContext, returnByValue: boolean, pageFunction: Function | string, ...args: any[]): Promise<any> {
 | 
			
		||||
 | 
			
		||||
@ -116,6 +116,10 @@ export class WKExecutionContext implements js.ExecutionContextDelegate {
 | 
			
		||||
  async releaseHandle(objectId: js.ObjectId): Promise<void> {
 | 
			
		||||
    await this._session.send('Runtime.releaseObject', { objectId });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  objectCount(objectId: js.ObjectId): Promise<number> {
 | 
			
		||||
    throw new Error('Method not implemented in WebKit.');
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function potentiallyUnserializableValue(remoteObject: Protocol.Runtime.RemoteObject): any {
 | 
			
		||||
 | 
			
		||||
@ -2976,6 +2976,7 @@ export interface JSHandleChannel extends JSHandleEventTarget, Channel {
 | 
			
		||||
  getPropertyList(params?: JSHandleGetPropertyListParams, metadata?: CallMetadata): Promise<JSHandleGetPropertyListResult>;
 | 
			
		||||
  getProperty(params: JSHandleGetPropertyParams, metadata?: CallMetadata): Promise<JSHandleGetPropertyResult>;
 | 
			
		||||
  jsonValue(params?: JSHandleJsonValueParams, metadata?: CallMetadata): Promise<JSHandleJsonValueResult>;
 | 
			
		||||
  objectCount(params?: JSHandleObjectCountParams, metadata?: CallMetadata): Promise<JSHandleObjectCountResult>;
 | 
			
		||||
}
 | 
			
		||||
export type JSHandlePreviewUpdatedEvent = {
 | 
			
		||||
  preview: string,
 | 
			
		||||
@ -3027,6 +3028,11 @@ export type JSHandleJsonValueOptions = {};
 | 
			
		||||
export type JSHandleJsonValueResult = {
 | 
			
		||||
  value: SerializedValue,
 | 
			
		||||
};
 | 
			
		||||
export type JSHandleObjectCountParams = {};
 | 
			
		||||
export type JSHandleObjectCountOptions = {};
 | 
			
		||||
export type JSHandleObjectCountResult = {
 | 
			
		||||
  count: number,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export interface JSHandleEvents {
 | 
			
		||||
  'previewUpdated': JSHandlePreviewUpdatedEvent;
 | 
			
		||||
 | 
			
		||||
@ -2295,6 +2295,10 @@ JSHandle:
 | 
			
		||||
      returns:
 | 
			
		||||
        value: SerializedValue
 | 
			
		||||
 | 
			
		||||
    objectCount:
 | 
			
		||||
      returns:
 | 
			
		||||
        count: number
 | 
			
		||||
 | 
			
		||||
  events:
 | 
			
		||||
 | 
			
		||||
    previewUpdated:
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										25
									
								
								tests/page/page-object-count.spec.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								tests/page/page-object-count.spec.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,25 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (c) Microsoft Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import { test, expect } from './pageTest';
 | 
			
		||||
 | 
			
		||||
test('should count objects', async ({ page, browserName }) => {
 | 
			
		||||
  test.skip(browserName !== 'chromium');
 | 
			
		||||
  await page.setContent('<button>Submit</button>');
 | 
			
		||||
  await page.evaluate(() => document.querySelectorAll('button'));
 | 
			
		||||
  const proto = await page.evaluateHandle(() => HTMLButtonElement.prototype);
 | 
			
		||||
  expect(await (proto as any)._objectCount()).toBe(1);
 | 
			
		||||
});
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user