How to use awaitViewportDimensions method in Playwright Internal

Best JavaScript code snippet using playwright-internal

TargetRegistry.js

Source:TargetRegistry.js Github

copy

Full Screen

1/* This Source Code Form is subject to the terms of the Mozilla Public2 * License, v. 2.0. If a copy of the MPL was not distributed with this3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */4const {EventEmitter} = ChromeUtils.import('resource://gre/modules/EventEmitter.jsm');5const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');6const {SimpleChannel} = ChromeUtils.import('chrome://juggler/content/SimpleChannel.js');7const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");8const {Preferences} = ChromeUtils.import("resource://gre/modules/Preferences.jsm");9const {ContextualIdentityService} = ChromeUtils.import("resource://gre/modules/ContextualIdentityService.jsm");10const {NetUtil} = ChromeUtils.import('resource://gre/modules/NetUtil.jsm');11const {AppConstants} = ChromeUtils.import("resource://gre/modules/AppConstants.jsm");12const {OS} = ChromeUtils.import("resource://gre/modules/osfile.jsm");13const helper = new Helper();14const IDENTITY_NAME = 'JUGGLER ';15const HUNDRED_YEARS = 60 * 60 * 24 * 365 * 100;16const ALL_PERMISSIONS = [17 'geo',18 'desktop-notification',19];20class DownloadInterceptor {21 constructor(registry) {22 this._registry = registry23 this._handlerToUuid = new Map();24 }25 //26 // nsIDownloadInterceptor implementation.27 //28 interceptDownloadRequest(externalAppHandler, request, browsingContext, outFile) {29 if (!(request instanceof Ci.nsIChannel))30 return false;31 const channel = request.QueryInterface(Ci.nsIChannel);32 let pageTarget = this._registry._browserBrowsingContextToTarget.get(channel.loadInfo.browsingContext);33 if (!pageTarget)34 return false;35 const browserContext = pageTarget.browserContext();36 const options = browserContext.downloadOptions;37 if (!options)38 return false;39 const uuid = helper.generateId();40 let file = null;41 if (options.behavior === 'saveToDisk') {42 file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);43 file.initWithPath(options.downloadsDir);44 file.append(uuid);45 try {46 file.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0o600);47 } catch (e) {48 dump(`interceptDownloadRequest failed to create file: ${e}\n`);49 return false;50 }51 }52 outFile.value = file;53 this._handlerToUuid.set(externalAppHandler, uuid);54 const downloadInfo = {55 uuid,56 browserContextId: browserContext.browserContextId,57 pageTargetId: pageTarget.id(),58 url: request.name,59 suggestedFileName: externalAppHandler.suggestedFileName,60 };61 this._registry.emit(TargetRegistry.Events.DownloadCreated, downloadInfo);62 return true;63 }64 onDownloadComplete(externalAppHandler, canceled, errorName) {65 const uuid = this._handlerToUuid.get(externalAppHandler);66 if (!uuid)67 return;68 this._handlerToUuid.delete(externalAppHandler);69 const downloadInfo = {70 uuid,71 };72 if (errorName === 'NS_BINDING_ABORTED') {73 downloadInfo.canceled = true;74 } else {75 downloadInfo.error = errorName;76 }77 this._registry.emit(TargetRegistry.Events.DownloadFinished, downloadInfo);78 }79}80class TargetRegistry {81 constructor() {82 EventEmitter.decorate(this);83 this._browserContextIdToBrowserContext = new Map();84 this._userContextIdToBrowserContext = new Map();85 this._browserToTarget = new Map();86 this._browserBrowsingContextToTarget = new Map();87 this._browserProxy = null;88 // Cleanup containers from previous runs (if any)89 for (const identity of ContextualIdentityService.getPublicIdentities()) {90 if (identity.name && identity.name.startsWith(IDENTITY_NAME)) {91 ContextualIdentityService.remove(identity.userContextId);92 ContextualIdentityService.closeContainerTabs(identity.userContextId);93 }94 }95 this._defaultContext = new BrowserContext(this, undefined, undefined);96 Services.obs.addObserver({97 observe: (subject, topic, data) => {98 const browser = subject.ownerElement;99 if (!browser)100 return;101 const target = this._browserToTarget.get(browser);102 if (!target)103 return;104 target.emit(PageTarget.Events.Crashed);105 target.dispose();106 }107 }, 'oop-frameloader-crashed');108 Services.mm.addMessageListener('juggler:content-ready', {109 receiveMessage: message => {110 const linkedBrowser = message.target;111 const target = this._browserToTarget.get(linkedBrowser);112 if (!target)113 return;114 return {115 scriptsToEvaluateOnNewDocument: target.browserContext().scriptsToEvaluateOnNewDocument,116 bindings: target.browserContext().bindings,117 settings: target.browserContext().settings,118 };119 },120 });121 const onTabOpenListener = (appWindow, window, event) => {122 const tab = event.target;123 const userContextId = tab.userContextId;124 const browserContext = this._userContextIdToBrowserContext.get(userContextId);125 const hasExplicitSize = appWindow && (appWindow.chromeFlags & Ci.nsIWebBrowserChrome.JUGGLER_WINDOW_EXPLICIT_SIZE) !== 0;126 const openerContext = tab.linkedBrowser.browsingContext.opener;127 let openerTarget;128 if (openerContext) {129 // Popups usually have opener context.130 openerTarget = this._browserBrowsingContextToTarget.get(openerContext);131 } else if (tab.openerTab) {132 // Noopener popups from the same window have opener tab instead.133 openerTarget = this._browserToTarget.get(tab.openerTab.linkedBrowser);134 }135 if (!browserContext)136 throw new Error(`Internal error: cannot find context for userContextId=${userContextId}`);137 const target = new PageTarget(this, window, tab, browserContext, openerTarget);138 target.updateUserAgent();139 target.updateTouchOverride();140 target.updateColorSchemeOverride();141 if (!hasExplicitSize)142 target.updateViewportSize();143 if (browserContext.screencastOptions)144 target._startVideoRecording(browserContext.screencastOptions);145 };146 const onTabCloseListener = event => {147 const tab = event.target;148 const linkedBrowser = tab.linkedBrowser;149 const target = this._browserToTarget.get(linkedBrowser);150 if (target)151 target.dispose();152 };153 const domWindowTabListeners = new Map();154 const onOpenWindow = async (appWindow) => {155 let domWindow;156 if (appWindow instanceof Ci.nsIAppWindow) {157 domWindow = appWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);158 } else {159 domWindow = appWindow;160 appWindow = null;161 }162 if (!(domWindow instanceof Ci.nsIDOMChromeWindow))163 return;164 // In persistent mode, window might be opened long ago and might be165 // already initialized.166 //167 // In this case, we want to keep this callback synchronous so that we will call168 // `onTabOpenListener` synchronously and before the sync IPc message `juggler:content-ready`.169 if (domWindow.document.readyState === 'uninitialized' || domWindow.document.readyState === 'loading') {170 // For non-initialized windows, DOMContentLoaded initializes gBrowser171 // and starts tab loading (see //browser/base/content/browser.js), so we172 // are guaranteed to call `onTabOpenListener` before the sync IPC message173 // `juggler:content-ready`.174 await helper.awaitEvent(domWindow, 'DOMContentLoaded');175 }176 if (!domWindow.gBrowser)177 return;178 const tabContainer = domWindow.gBrowser.tabContainer;179 domWindowTabListeners.set(domWindow, [180 helper.addEventListener(tabContainer, 'TabOpen', event => onTabOpenListener(appWindow, domWindow, event)),181 helper.addEventListener(tabContainer, 'TabClose', onTabCloseListener),182 ]);183 for (const tab of domWindow.gBrowser.tabs)184 onTabOpenListener(appWindow, domWindow, { target: tab });185 };186 const onCloseWindow = window => {187 const domWindow = window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);188 if (!(domWindow instanceof Ci.nsIDOMChromeWindow))189 return;190 if (!domWindow.gBrowser)191 return;192 const listeners = domWindowTabListeners.get(domWindow) || [];193 domWindowTabListeners.delete(domWindow);194 helper.removeListeners(listeners);195 for (const tab of domWindow.gBrowser.tabs)196 onTabCloseListener({ target: tab });197 };198 const extHelperAppSvc = Cc["@mozilla.org/uriloader/external-helper-app-service;1"].getService(Ci.nsIExternalHelperAppService);199 extHelperAppSvc.setDownloadInterceptor(new DownloadInterceptor(this));200 Services.wm.addListener({ onOpenWindow, onCloseWindow });201 for (const win of Services.wm.getEnumerator(null))202 onOpenWindow(win);203 }204 setBrowserProxy(proxy) {205 this._browserProxy = proxy;206 }207 getProxyInfo(channel) {208 const originAttributes = channel.loadInfo && channel.loadInfo.originAttributes;209 const browserContext = originAttributes ? this.browserContextForUserContextId(originAttributes.userContextId) : null;210 // Prefer context proxy and fallback to browser-level proxy.211 const proxyInfo = (browserContext && browserContext._proxy) || this._browserProxy;212 if (!proxyInfo || proxyInfo.bypass.some(domainSuffix => channel.URI.host.endsWith(domainSuffix)))213 return null;214 return proxyInfo;215 }216 defaultContext() {217 return this._defaultContext;218 }219 createBrowserContext(removeOnDetach) {220 return new BrowserContext(this, helper.generateId(), removeOnDetach);221 }222 browserContextForId(browserContextId) {223 return this._browserContextIdToBrowserContext.get(browserContextId);224 }225 browserContextForUserContextId(userContextId) {226 return this._userContextIdToBrowserContext.get(userContextId);227 }228 async newPage({browserContextId}) {229 const browserContext = this.browserContextForId(browserContextId);230 const features = "chrome,dialog=no,all";231 // See _callWithURIToLoad in browser.js for the structure of window.arguments232 // window.arguments[1]: unused (bug 871161)233 // [2]: referrerInfo (nsIReferrerInfo)234 // [3]: postData (nsIInputStream)235 // [4]: allowThirdPartyFixup (bool)236 // [5]: userContextId (int)237 // [6]: originPrincipal (nsIPrincipal)238 // [7]: originStoragePrincipal (nsIPrincipal)239 // [8]: triggeringPrincipal (nsIPrincipal)240 // [9]: allowInheritPrincipal (bool)241 // [10]: csp (nsIContentSecurityPolicy)242 // [11]: nsOpenWindowInfo243 const args = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);244 const urlSupports = Cc["@mozilla.org/supports-string;1"].createInstance(245 Ci.nsISupportsString246 );247 urlSupports.data = 'about:blank';248 args.appendElement(urlSupports); // 0249 args.appendElement(undefined); // 1250 args.appendElement(undefined); // 2251 args.appendElement(undefined); // 3252 args.appendElement(undefined); // 4253 const userContextIdSupports = Cc[254 "@mozilla.org/supports-PRUint32;1"255 ].createInstance(Ci.nsISupportsPRUint32);256 userContextIdSupports.data = browserContext.userContextId;257 args.appendElement(userContextIdSupports); // 5258 args.appendElement(undefined); // 6259 args.appendElement(undefined); // 7260 args.appendElement(Services.scriptSecurityManager.getSystemPrincipal()); // 8261 const window = Services.ww.openWindow(null, AppConstants.BROWSER_CHROME_URL, '_blank', features, args);262 await waitForWindowReady(window);263 if (window.gBrowser.browsers.length !== 1)264 throw new Error(`Unexpected number of tabs in the new window: ${window.gBrowser.browsers.length}`);265 const browser = window.gBrowser.browsers[0];266 const target = this._browserToTarget.get(browser);267 browser.focus();268 if (browserContext.settings.timezoneId) {269 if (await target.hasFailedToOverrideTimezone())270 throw new Error('Failed to override timezone');271 }272 return target.id();273 }274 targets() {275 return Array.from(this._browserToTarget.values());276 }277 targetForBrowser(browser) {278 return this._browserToTarget.get(browser);279 }280}281class PageTarget {282 constructor(registry, win, tab, browserContext, opener) {283 EventEmitter.decorate(this);284 this._targetId = helper.generateId();285 this._registry = registry;286 this._window = win;287 this._gBrowser = win.gBrowser;288 this._tab = tab;289 this._linkedBrowser = tab.linkedBrowser;290 this._browserContext = browserContext;291 this._viewportSize = undefined;292 this._initialDPPX = this._linkedBrowser.browsingContext.overrideDPPX;293 this._url = 'about:blank';294 this._openerId = opener ? opener.id() : undefined;295 this._channel = SimpleChannel.createForMessageManager(`browser::page[${this._targetId}]`, this._linkedBrowser.messageManager);296 this._screencastInfo = undefined;297 this._dialogs = new Map();298 const navigationListener = {299 QueryInterface: ChromeUtils.generateQI([Ci.nsIWebProgressListener, Ci.nsISupportsWeakReference]),300 onLocationChange: (aWebProgress, aRequest, aLocation) => this._onNavigated(aLocation),301 };302 this._eventListeners = [303 helper.addObserver(this._updateModalDialogs.bind(this), 'tabmodal-dialog-loaded'),304 helper.addProgressListener(tab.linkedBrowser, navigationListener, Ci.nsIWebProgress.NOTIFY_LOCATION),305 helper.addEventListener(this._linkedBrowser, 'DOMModalDialogClosed', event => this._updateModalDialogs()),306 ];307 this._disposed = false;308 browserContext.pages.add(this);309 this._registry._browserToTarget.set(this._linkedBrowser, this);310 this._registry._browserBrowsingContextToTarget.set(this._linkedBrowser.browsingContext, this);311 this._registry.emit(TargetRegistry.Events.TargetCreated, this);312 }313 dialog(dialogId) {314 return this._dialogs.get(dialogId);315 }316 dialogs() {317 return [...this._dialogs.values()];318 }319 async windowReady() {320 await waitForWindowReady(this._window);321 }322 linkedBrowser() {323 return this._linkedBrowser;324 }325 browserContext() {326 return this._browserContext;327 }328 updateTouchOverride() {329 this._linkedBrowser.browsingContext.touchEventsOverride = this._browserContext.touchOverride ? 'enabled' : 'none';330 }331 updateUserAgent() {332 this._linkedBrowser.browsingContext.customUserAgent = this._browserContext.defaultUserAgent;333 }334 _updateModalDialogs() {335 const prompts = new Set(this._linkedBrowser.tabModalPromptBox ? this._linkedBrowser.tabModalPromptBox.listPrompts() : []);336 for (const dialog of this._dialogs.values()) {337 if (!prompts.has(dialog.prompt())) {338 this._dialogs.delete(dialog.id());339 this.emit(PageTarget.Events.DialogClosed, dialog);340 } else {341 prompts.delete(dialog.prompt());342 }343 }344 for (const prompt of prompts) {345 const dialog = Dialog.createIfSupported(prompt);346 if (!dialog)347 continue;348 this._dialogs.set(dialog.id(), dialog);349 this.emit(PageTarget.Events.DialogOpened, dialog);350 }351 }352 async updateViewportSize() {353 // Viewport size is defined by three arguments:354 // 1. default size. Could be explicit if set as part of `window.open` call, e.g.355 // `window.open(url, title, 'width=400,height=400')`356 // 2. page viewport size357 // 3. browserContext viewport size358 //359 // The "default size" (1) is only respected when the page is opened.360 // Otherwise, explicitly set page viewport prevales over browser context361 // default viewport.362 const viewportSize = this._viewportSize || this._browserContext.defaultViewportSize;363 const actualSize = await setViewportSizeForBrowser(viewportSize, this._linkedBrowser, this._window);364 this._linkedBrowser.browsingContext.overrideDPPX = this._browserContext.deviceScaleFactor || this._initialDPPX;365 await this._channel.connect('').send('awaitViewportDimensions', {366 width: actualSize.width,367 height: actualSize.height,368 deviceSizeIsPageSize: !!this._browserContext.deviceScaleFactor,369 });370 }371 setEmulatedMedia(mediumOverride) {372 this._linkedBrowser.browsingContext.mediumOverride = mediumOverride || '';373 }374 setColorScheme(colorScheme) {375 this.colorScheme = fromProtocolColorScheme(colorScheme);376 this.updateColorSchemeOverride();377 }378 updateColorSchemeOverride() {379 this._linkedBrowser.browsingContext.prefersColorSchemeOverride = this.colorScheme || this._browserContext.colorScheme || 'none';380 }381 async setViewportSize(viewportSize) {382 this._viewportSize = viewportSize;383 await this.updateViewportSize();384 }385 close(runBeforeUnload = false) {386 this._gBrowser.removeTab(this._tab, {387 skipPermitUnload: !runBeforeUnload,388 });389 }390 channel() {391 return this._channel;392 }393 id() {394 return this._targetId;395 }396 info() {397 return {398 targetId: this.id(),399 type: 'page',400 browserContextId: this._browserContext.browserContextId,401 openerId: this._openerId,402 };403 }404 _onNavigated(aLocation) {405 this._url = aLocation.spec;406 this._browserContext.grantPermissionsToOrigin(this._url);407 }408 async ensurePermissions() {409 await this._channel.connect('').send('ensurePermissions', {}).catch(e => void e);410 }411 async addScriptToEvaluateOnNewDocument(script) {412 await this._channel.connect('').send('addScriptToEvaluateOnNewDocument', script).catch(e => void e);413 }414 async addBinding(name, script) {415 await this._channel.connect('').send('addBinding', { name, script }).catch(e => void e);416 }417 async applyContextSetting(name, value) {418 await this._channel.connect('').send('applyContextSetting', { name, value }).catch(e => void e);419 }420 async hasFailedToOverrideTimezone() {421 return await this._channel.connect('').send('hasFailedToOverrideTimezone').catch(e => true);422 }423 async _startVideoRecording({width, height, scale, dir}) {424 // On Mac the window may not yet be visible when TargetCreated and its425 // NSWindow.windowNumber may be -1, so we wait until the window is known426 // to be initialized and visible.427 await this.windowReady();428 const file = OS.Path.join(dir, helper.generateId() + '.webm');429 if (width < 10 || width > 10000 || height < 10 || height > 10000)430 throw new Error("Invalid size");431 if (scale && (scale <= 0 || scale > 1))432 throw new Error("Unsupported scale");433 const screencast = Cc['@mozilla.org/juggler/screencast;1'].getService(Ci.nsIScreencastService);434 const docShell = this._gBrowser.ownerGlobal.docShell;435 // Exclude address bar and navigation control from the video.436 const rect = this.linkedBrowser().getBoundingClientRect();437 const devicePixelRatio = this._window.devicePixelRatio;438 const videoSessionId = screencast.startVideoRecording(docShell, file, width, height, scale || 0, devicePixelRatio * rect.top);439 this._screencastInfo = { videoSessionId, file };440 this.emit(PageTarget.Events.ScreencastStarted);441 }442 async _stopVideoRecording() {443 if (!this._screencastInfo)444 throw new Error('No video recording in progress');445 const screencastInfo = this._screencastInfo;446 this._screencastInfo = undefined;447 const screencast = Cc['@mozilla.org/juggler/screencast;1'].getService(Ci.nsIScreencastService);448 const result = new Promise(resolve =>449 Services.obs.addObserver(function onStopped(subject, topic, data) {450 if (screencastInfo.videoSessionId != data)451 return;452 Services.obs.removeObserver(onStopped, 'juggler-screencast-stopped');453 resolve();454 }, 'juggler-screencast-stopped')455 );456 screencast.stopVideoRecording(screencastInfo.videoSessionId);457 return result;458 }459 screencastInfo() {460 return this._screencastInfo;461 }462 dispose() {463 this._disposed = true;464 if (this._screencastInfo)465 this._stopVideoRecording().catch(e => dump(`stopVideoRecording failed:\n${e}\n`));466 this._browserContext.pages.delete(this);467 this._registry._browserToTarget.delete(this._linkedBrowser);468 this._registry._browserBrowsingContextToTarget.delete(this._linkedBrowser.browsingContext);469 try {470 helper.removeListeners(this._eventListeners);471 } catch (e) {472 // In some cases, removing listeners from this._linkedBrowser fails473 // because it is already half-destroyed.474 if (e)475 dump(e.message + '\n' + e.stack + '\n');476 }477 this._registry.emit(TargetRegistry.Events.TargetDestroyed, this);478 }479}480PageTarget.Events = {481 ScreencastStarted: Symbol('PageTarget.ScreencastStarted'),482 Crashed: Symbol('PageTarget.Crashed'),483 DialogOpened: Symbol('PageTarget.DialogOpened'),484 DialogClosed: Symbol('PageTarget.DialogClosed'),485};486function fromProtocolColorScheme(colorScheme) {487 if (colorScheme === 'light' || colorScheme === 'dark')488 return colorScheme;489 if (colorScheme === null || colorScheme === 'no-preference')490 return undefined;491 throw new Error('Unknown color scheme: ' + colorScheme);492}493class BrowserContext {494 constructor(registry, browserContextId, removeOnDetach) {495 this._registry = registry;496 this.browserContextId = browserContextId;497 // Default context has userContextId === 0, but we pass undefined to many APIs just in case.498 this.userContextId = 0;499 if (browserContextId !== undefined) {500 const identity = ContextualIdentityService.create(IDENTITY_NAME + browserContextId);501 this.userContextId = identity.userContextId;502 }503 this._principals = [];504 // Maps origins to the permission lists.505 this._permissions = new Map();506 this._registry._browserContextIdToBrowserContext.set(this.browserContextId, this);507 this._registry._userContextIdToBrowserContext.set(this.userContextId, this);508 this._proxy = null;509 this.removeOnDetach = removeOnDetach;510 this.extraHTTPHeaders = undefined;511 this.httpCredentials = undefined;512 this.requestInterceptionEnabled = undefined;513 this.ignoreHTTPSErrors = undefined;514 this.downloadOptions = undefined;515 this.defaultViewportSize = undefined;516 this.deviceScaleFactor = undefined;517 this.defaultUserAgent = null;518 this.touchOverride = false;519 this.colorScheme = 'none';520 this.screencastOptions = undefined;521 this.scriptsToEvaluateOnNewDocument = [];522 this.bindings = [];523 this.settings = {};524 this.pages = new Set();525 }526 setColorScheme(colorScheme) {527 this.colorScheme = fromProtocolColorScheme(colorScheme);528 for (const page of this.pages)529 page.updateColorSchemeOverride();530 }531 async destroy() {532 if (this.userContextId !== 0) {533 ContextualIdentityService.remove(this.userContextId);534 for (const page of this.pages)535 page.close();536 if (this.pages.size) {537 await new Promise(f => {538 const listener = helper.on(this._registry, TargetRegistry.Events.TargetDestroyed, () => {539 if (!this.pages.size) {540 helper.removeListeners([listener]);541 f();542 }543 });544 });545 }546 }547 this._registry._browserContextIdToBrowserContext.delete(this.browserContextId);548 this._registry._userContextIdToBrowserContext.delete(this.userContextId);549 }550 setProxy(proxy) {551 // Clear AuthCache.552 Services.obs.notifyObservers(null, "net:clear-active-logins");553 this._proxy = proxy;554 }555 setIgnoreHTTPSErrors(ignoreHTTPSErrors) {556 if (this.ignoreHTTPSErrors === ignoreHTTPSErrors)557 return;558 this.ignoreHTTPSErrors = ignoreHTTPSErrors;559 const certOverrideService = Cc[560 "@mozilla.org/security/certoverride;1"561 ].getService(Ci.nsICertOverrideService);562 if (ignoreHTTPSErrors) {563 Preferences.set("network.stricttransportsecurity.preloadlist", false);564 Preferences.set("security.cert_pinning.enforcement_level", 0);565 certOverrideService.setDisableAllSecurityChecksAndLetAttackersInterceptMyData(true, this.userContextId);566 } else {567 certOverrideService.setDisableAllSecurityChecksAndLetAttackersInterceptMyData(false, this.userContextId);568 }569 }570 async setDefaultUserAgent(userAgent) {571 this.defaultUserAgent = userAgent;572 for (const page of this.pages)573 page.updateUserAgent();574 }575 setTouchOverride(touchOverride) {576 this.touchOverride = touchOverride;577 for (const page of this.pages)578 page.updateTouchOverride();579 }580 async setDefaultViewport(viewport) {581 this.defaultViewportSize = viewport ? viewport.viewportSize : undefined;582 this.deviceScaleFactor = viewport ? viewport.deviceScaleFactor : undefined;583 await Promise.all(Array.from(this.pages).map(page => page.updateViewportSize()));584 }585 async addScriptToEvaluateOnNewDocument(script) {586 this.scriptsToEvaluateOnNewDocument.push(script);587 await Promise.all(Array.from(this.pages).map(page => page.addScriptToEvaluateOnNewDocument(script)));588 }589 async addBinding(name, script) {590 this.bindings.push({ name, script });591 await Promise.all(Array.from(this.pages).map(page => page.addBinding(name, script)));592 }593 async applySetting(name, value) {594 this.settings[name] = value;595 await Promise.all(Array.from(this.pages).map(page => page.applyContextSetting(name, value)));596 }597 async grantPermissions(origin, permissions) {598 this._permissions.set(origin, permissions);599 const promises = [];600 for (const page of this.pages) {601 if (origin === '*' || page._url.startsWith(origin)) {602 this.grantPermissionsToOrigin(page._url);603 promises.push(page.ensurePermissions());604 }605 }606 await Promise.all(promises);607 }608 resetPermissions() {609 for (const principal of this._principals) {610 for (const permission of ALL_PERMISSIONS)611 Services.perms.removeFromPrincipal(principal, permission);612 }613 this._principals = [];614 this._permissions.clear();615 }616 grantPermissionsToOrigin(url) {617 let origin = Array.from(this._permissions.keys()).find(key => url.startsWith(key));618 if (!origin)619 origin = '*';620 const permissions = this._permissions.get(origin);621 if (!permissions)622 return;623 const attrs = { userContextId: this.userContextId || undefined };624 const principal = Services.scriptSecurityManager.createContentPrincipal(NetUtil.newURI(url), attrs);625 this._principals.push(principal);626 for (const permission of ALL_PERMISSIONS) {627 const action = permissions.includes(permission) ? Ci.nsIPermissionManager.ALLOW_ACTION : Ci.nsIPermissionManager.DENY_ACTION;628 Services.perms.addFromPrincipal(principal, permission, action, Ci.nsIPermissionManager.EXPIRE_NEVER, 0 /* expireTime */);629 }630 }631 setCookies(cookies) {632 const protocolToSameSite = {633 [undefined]: Ci.nsICookie.SAMESITE_NONE,634 'Lax': Ci.nsICookie.SAMESITE_LAX,635 'Strict': Ci.nsICookie.SAMESITE_STRICT,636 };637 for (const cookie of cookies) {638 const uri = cookie.url ? NetUtil.newURI(cookie.url) : null;639 let domain = cookie.domain;640 if (!domain) {641 if (!uri)642 throw new Error('At least one of the url and domain needs to be specified');643 domain = uri.host;644 }645 let path = cookie.path;646 if (!path)647 path = uri ? dirPath(uri.filePath) : '/';648 let secure = false;649 if (cookie.secure !== undefined)650 secure = cookie.secure;651 else if (uri && uri.scheme === 'https')652 secure = true;653 Services.cookies.add(654 domain,655 path,656 cookie.name,657 cookie.value,658 secure,659 cookie.httpOnly || false,660 cookie.expires === undefined || cookie.expires === -1 /* isSession */,661 cookie.expires === undefined ? Date.now() + HUNDRED_YEARS : cookie.expires,662 { userContextId: this.userContextId || undefined } /* originAttributes */,663 protocolToSameSite[cookie.sameSite],664 Ci.nsICookie.SCHEME_UNSET665 );666 }667 }668 clearCookies() {669 Services.cookies.removeCookiesWithOriginAttributes(JSON.stringify({ userContextId: this.userContextId || undefined }));670 }671 getCookies() {672 const result = [];673 const sameSiteToProtocol = {674 [Ci.nsICookie.SAMESITE_NONE]: 'None',675 [Ci.nsICookie.SAMESITE_LAX]: 'Lax',676 [Ci.nsICookie.SAMESITE_STRICT]: 'Strict',677 };678 for (let cookie of Services.cookies.cookies) {679 if (cookie.originAttributes.userContextId !== this.userContextId)680 continue;681 if (cookie.host === 'addons.mozilla.org')682 continue;683 result.push({684 name: cookie.name,685 value: cookie.value,686 domain: cookie.host,687 path: cookie.path,688 expires: cookie.isSession ? -1 : cookie.expiry,689 size: cookie.name.length + cookie.value.length,690 httpOnly: cookie.isHttpOnly,691 secure: cookie.isSecure,692 session: cookie.isSession,693 sameSite: sameSiteToProtocol[cookie.sameSite],694 });695 }696 return result;697 }698 async setScreencastOptions(options) {699 this.screencastOptions = options;700 if (!options)701 return;702 const promises = [];703 for (const page of this.pages)704 promises.push(page._startVideoRecording(options));705 await Promise.all(promises);706 }707}708class Dialog {709 static createIfSupported(prompt) {710 const type = prompt.args.promptType;711 switch (type) {712 case 'alert':713 case 'alertCheck':714 return new Dialog(prompt, 'alert');715 case 'prompt':716 return new Dialog(prompt, 'prompt');717 case 'confirm':718 case 'confirmCheck':719 return new Dialog(prompt, 'confirm');720 case 'confirmEx':721 return new Dialog(prompt, 'beforeunload');722 default:723 return null;724 };725 }726 constructor(prompt, type) {727 this._id = helper.generateId();728 this._type = type;729 this._prompt = prompt;730 }731 id() {732 return this._id;733 }734 message() {735 return this._prompt.ui.infoBody.textContent;736 }737 type() {738 return this._type;739 }740 prompt() {741 return this._prompt;742 }743 dismiss() {744 if (this._prompt.ui.button1)745 this._prompt.ui.button1.click();746 else747 this._prompt.ui.button0.click();748 }749 defaultValue() {750 return this._prompt.ui.loginTextbox.value;751 }752 accept(promptValue) {753 if (typeof promptValue === 'string' && this._type === 'prompt')754 this._prompt.ui.loginTextbox.value = promptValue;755 this._prompt.ui.button0.click();756 }757}758function dirPath(path) {759 return path.substring(0, path.lastIndexOf('/') + 1);760}761async function waitForWindowReady(window) {762 if (window.delayedStartupPromise) {763 await window.delayedStartupPromise;764 } else {765 await new Promise((resolve => {766 Services.obs.addObserver(function observer(aSubject, aTopic) {767 if (window == aSubject) {768 Services.obs.removeObserver(observer, aTopic);769 resolve();770 }771 }, "browser-delayed-startup-finished");772 }));773 }774 if (window.document.readyState !== 'complete')775 await helper.awaitEvent(window, 'load');776}777async function setViewportSizeForBrowser(viewportSize, browser, window) {778 await waitForWindowReady(window);779 if (viewportSize) {780 const {width, height} = viewportSize;781 const rect = browser.getBoundingClientRect();782 window.resizeBy(width - rect.width, height - rect.height);783 browser.style.setProperty('min-width', width + 'px');784 browser.style.setProperty('min-height', height + 'px');785 browser.style.setProperty('max-width', width + 'px');786 browser.style.setProperty('max-height', height + 'px');787 } else {788 browser.style.removeProperty('min-width');789 browser.style.removeProperty('min-height');790 browser.style.removeProperty('max-width');791 browser.style.removeProperty('max-height');792 }793 const rect = browser.getBoundingClientRect();794 return { width: rect.width, height: rect.height };795}796TargetRegistry.Events = {797 TargetCreated: Symbol('TargetRegistry.Events.TargetCreated'),798 TargetDestroyed: Symbol('TargetRegistry.Events.TargetDestroyed'),799 DownloadCreated: Symbol('TargetRegistry.Events.DownloadCreated'),800 DownloadFinished: Symbol('TargetRegistry.Events.DownloadFinished'),801};802var EXPORTED_SYMBOLS = ['TargetRegistry', 'PageTarget'];803this.TargetRegistry = TargetRegistry;...

Full Screen

Full Screen

PageAgent.js

Source:PageAgent.js Github

copy

Full Screen

...18 const docShell = frameTree.mainFrame().docShell();19 this._initialDPPX = docShell.contentViewer.overrideDPPX;20 this._customScrollbars = null;21 }22 async awaitViewportDimensions({width, height}) {23 const win = this._frameTree.mainFrame().domWindow();24 if (win.innerWidth === width && win.innerHeight === height)25 return;26 await new Promise(resolve => {27 const listener = helper.addEventListener(win, 'resize', () => {28 if (win.innerWidth === width && win.innerHeight === height) {29 helper.removeListeners([listener]);30 resolve();31 }32 });33 });34 }35 async setViewport({deviceScaleFactor, isMobile, hasTouch}) {36 const docShell = this._frameTree.mainFrame().docShell();...

Full Screen

Full Screen

PageHandler.jsm

Source:PageHandler.jsm Github

copy

Full Screen

1"use strict";2const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');3const Cc = Components.classes;4const Ci = Components.interfaces;5const Cu = Components.utils;6const XUL_NS = 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul';7const FRAME_SCRIPT = "chrome://juggler/content/content/ContentSession.js";8const helper = new Helper();9class PageHandler {10 constructor(chromeSession, tab) {11 this._pageId = helper.generateId();12 this._chromeSession = chromeSession;13 this._tab = tab;14 this._browser = tab.linkedBrowser;15 this._enabled = false;16 this.QueryInterface = ChromeUtils.generateQI([17 Ci.nsIWebProgressListener,18 Ci.nsISupportsWeakReference,19 ]);20 this._browser.addProgressListener(this, Ci.nsIWebProgress.NOTIFY_LOCATION);21 this._dialogs = new Map();22 // First navigation always happens to about:blank - do not report it.23 this._skipNextNavigation = true;24 }25 async setViewport({viewport}) {26 if (viewport) {27 const {width, height} = viewport;28 this._browser.style.setProperty('min-width', width + 'px');29 this._browser.style.setProperty('min-height', height + 'px');30 this._browser.style.setProperty('max-width', width + 'px');31 this._browser.style.setProperty('max-height', height + 'px');32 } else {33 this._browser.style.removeProperty('min-width');34 this._browser.style.removeProperty('min-height');35 this._browser.style.removeProperty('max-width');36 this._browser.style.removeProperty('max-height');37 }38 const dimensions = this._browser.getBoundingClientRect();39 await Promise.all([40 this._contentSession.send('setViewport', {41 deviceScaleFactor: viewport ? viewport.deviceScaleFactor : 0,42 isMobile: viewport && viewport.isMobile,43 hasTouch: viewport && viewport.hasTouch,44 }),45 this._contentSession.send('awaitViewportDimensions', {46 width: dimensions.width,47 height: dimensions.height48 }),49 ]);50 }51 _initializeDialogEvents() {52 this._browser.addEventListener('DOMWillOpenModalDialog', async (event) => {53 // wait for the dialog to be actually added to DOM.54 await Promise.resolve();55 this._updateModalDialogs();56 });57 this._browser.addEventListener('DOMModalDialogClosed', (event) => {58 this._updateModalDialogs();59 });60 this._updateModalDialogs();61 }62 _updateModalDialogs() {63 const elements = new Set(this._browser.parentNode.getElementsByTagNameNS(XUL_NS, "tabmodalprompt"));64 for (const dialog of this._dialogs.values()) {65 if (!elements.has(dialog.element())) {66 this._dialogs.delete(dialog.id());67 this._chromeSession.emitEvent('Page.dialogClosed', {68 pageId: this._pageId,69 dialogId: dialog.id(),70 });71 } else {72 elements.delete(dialog.element());73 }74 }75 for (const element of elements) {76 const dialog = Dialog.createIfSupported(element);77 if (!dialog)78 continue;79 this._dialogs.set(dialog.id(), dialog);80 this._chromeSession.emitEvent('Page.dialogOpened', {81 pageId: this._pageId,82 dialogId: dialog.id(),83 type: dialog.type(),84 message: dialog.message(),85 defaultValue: dialog.defaultValue(),86 });87 }88 }89 onLocationChange(aWebProgress, aRequest, aLocation) {90 if (this._skipNextNavigation) {91 this._skipNextNavigation = false;92 return;93 }94 this._chromeSession.emitEvent('Browser.tabNavigated', {95 pageId: this._pageId,96 url: aLocation.spec97 });98 }99 url() {100 return this._browser.currentURI.spec;101 }102 tab() {103 return this._tab;104 }105 id() {106 return this._pageId;107 }108 async enable() {109 if (this._enabled)110 return;111 this._enabled = true;112 this._initializeDialogEvents();113 this._contentSession = new ContentSession(this._chromeSession, this._browser, this._pageId);114 await this._contentSession.send('enable');115 }116 async screenshot(options) {117 return await this._contentSession.send('screenshot', options);118 }119 async getBoundingBox(options) {120 return await this._contentSession.send('getBoundingBox', options);121 }122 async getContentQuads(options) {123 return await this._contentSession.send('getContentQuads', options);124 }125 /**126 * @param {{frameId: string, url: string}} options127 */128 async navigate(options) {129 return await this._contentSession.send('navigate', options);130 }131 /**132 * @param {{frameId: string, url: string}} options133 */134 async goBack(options) {135 return await this._contentSession.send('goBack', options);136 }137 /**138 * @param {{frameId: string, url: string}} options139 */140 async goForward(options) {141 return await this._contentSession.send('goForward', options);142 }143 /**144 * @param {{frameId: string, url: string}} options145 */146 async reload(options) {147 return await this._contentSession.send('reload', options);148 }149 /**150 * @param {{functionText: String, frameId: String}} options151 * @return {!Promise<*>}152 */153 async evaluate(options) {154 return await this._contentSession.send('evaluate', options);155 }156 async getObjectProperties(options) {157 return await this._contentSession.send('getObjectProperties', options);158 }159 async addScriptToEvaluateOnNewDocument(options) {160 return await this._contentSession.send('addScriptToEvaluateOnNewDocument', options);161 }162 async removeScriptToEvaluateOnNewDocument(options) {163 return await this._contentSession.send('removeScriptToEvaluateOnNewDocument', options);164 }165 async disposeObject(options) {166 return await this._contentSession.send('disposeObject', options);167 }168 async dispatchKeyEvent(options) {169 return await this._contentSession.send('dispatchKeyEvent', options);170 }171 async dispatchMouseEvent(options) {172 return await this._contentSession.send('dispatchMouseEvent', options);173 }174 async insertText(options) {175 return await this._contentSession.send('insertText', options);176 }177 async handleDialog({dialogId, accept, promptText}) {178 const dialog = this._dialogs.get(dialogId);179 if (!dialog)180 throw new Error('Failed to find dialog with id = ' + dialogId);181 if (accept)182 dialog.accept(promptText);183 else184 dialog.dismiss();185 }186 dispose() {187 this._browser.removeProgressListener(this);188 if (this._contentSession) {189 this._contentSession.dispose();190 this._contentSession = null;191 }192 }193}194class ContentSession {195 constructor(chromeSession, browser, pageId) {196 this._chromeSession = chromeSession;197 this._browser = browser;198 this._pageId = pageId;199 this._messageId = 0;200 this._pendingMessages = new Map();201 this._sessionId = helper.generateId();202 this._browser.messageManager.sendAsyncMessage('juggler:create-content-session', this._sessionId);203 this._eventListeners = [204 helper.addMessageListener(this._browser.messageManager, this._sessionId, {205 receiveMessage: message => this._onMessage(message)206 }),207 ];208 }209 dispose() {210 helper.removeListeners(this._eventListeners);211 for (const {resolve, reject} of this._pendingMessages.values())212 reject(new Error('Page closed.'));213 this._pendingMessages.clear();214 }215 /**216 * @param {string} methodName217 * @param {*} params218 * @return {!Promise<*>}219 */220 send(methodName, params) {221 const id = ++this._messageId;222 const promise = new Promise((resolve, reject) => {223 this._pendingMessages.set(id, {resolve, reject});224 });225 this._browser.messageManager.sendAsyncMessage(this._sessionId, {id, methodName, params});226 return promise;227 }228 _onMessage({data}) {229 if (data.id) {230 let id = data.id;231 const {resolve, reject} = this._pendingMessages.get(data.id);232 this._pendingMessages.delete(data.id);233 if (data.error)234 reject(new Error(data.error));235 else236 resolve(data.result);237 } else {238 const {239 eventName,240 params = {}241 } = data;242 params.pageId = this._pageId;243 this._chromeSession.emitEvent(eventName, params);244 }245 }246}247class Dialog {248 static createIfSupported(element) {249 const type = element.Dialog.args.promptType;250 switch (type) {251 case 'alert':252 case 'prompt':253 case 'confirm':254 return new Dialog(element, type);255 case 'confirmEx':256 return new Dialog(element, 'beforeunload');257 default:258 return null;259 };260 }261 constructor(element, type) {262 this._id = helper.generateId();263 this._type = type;264 this._element = element;265 }266 id() {267 return this._id;268 }269 message() {270 return this._element.ui.infoBody.textContent;271 }272 type() {273 return this._type;274 }275 element() {276 return this._element;277 }278 dismiss() {279 if (this._element.ui.button1)280 this._element.ui.button1.click();281 else282 this._element.ui.button0.click();283 }284 defaultValue() {285 return this._element.ui.loginTextbox.value;286 }287 accept(promptValue) {288 if (typeof promptValue === 'string' && this._type === 'prompt')289 this._element.ui.loginTextbox.value = promptValue;290 this._element.ui.button0.click();291 }292}293var EXPORTED_SYMBOLS = ['PageHandler'];...

Full Screen

Full Screen

main.js

Source:main.js Github

copy

Full Screen

...95 },96 hasFailedToOverrideTimezone() {97 return failedToOverrideTimezone;98 },99 async awaitViewportDimensions({width, height, deviceSizeIsPageSize}) {100 docShell.deviceSizeIsPageSize = deviceSizeIsPageSize;101 const win = docShell.domWindow;102 if (win.innerWidth === width && win.innerHeight === height)103 return;104 await new Promise(resolve => {105 const listener = helper.addEventListener(win, 'resize', () => {106 if (win.innerWidth === width && win.innerHeight === height) {107 helper.removeListeners([listener]);108 resolve();109 }110 });111 });112 },113 dispose() {...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1const playwright = require('playwright');2(async () => {3 for (const browserType of ['chromium', 'firefox', 'webkit']) {4 const browser = await playwright[browserType].launch();5 const context = await browser.newContext();6 const page = await context.newPage();7 await page.waitForSelector('h1');8 const dimensions = await page._client.send('Emulation.getVisibleSize');9 console.log(dimensions);10 await browser.close();11 }12})();13{ width: 800, height: 600 }14{ width: 800, height: 600 }15{ width: 800, height: 600 }

Full Screen

Using AI Code Generation

copy

Full Screen

1const playwright = require('playwright');2(async () => {3 const browser = await playwright['chromium'].launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.waitForLoadState('networkidle');7 const dimensions = await page.evaluate(() => {8 return {9 };10 });11 console.log('Dimensions:', dimensions);12 await browser.close();13})();14const playwright = require('playwright');15(async () => {16 const browser = await playwright['chromium'].launch();17 const context = await browser.newContext();18 const page = await context.newPage();19 await page.waitForLoadState('networkidle');20 await page.waitForViewportDimensions({21 });22 const dimensions = await page.evaluate(() => {23 return {24 };25 });26 console.log('Dimensions:', dimensions);27 await browser.close();28})();29const playwright = require('playwright');30(async () => {31 const browser = await playwright['chromium'].launch();32 const context = await browser.newContext();33 const page = await context.newPage();34 await page.waitForLoadState('networkidle');35 await page.waitForViewportDimensions({36 });37 const dimensions = await page.evaluate(() => {38 return {39 };40 });41 console.log('Dimensions:', dimensions);42 await browser.close();43})();44const playwright = require('playwright');45(async () => {46 const browser = await playwright['chromium'].launch();47 const context = await browser.newContext();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 const { width, height } = await page._delegate.awaitViewportDimensions();7 console.log(width, height);8 await browser.close();9})();

Full Screen

Using AI Code Generation

copy

Full Screen

1const playwright = require('playwright');2(async () => {3 const browser = await playwright.chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 const dimensions = await page._delegate._mainFrameSession._client.send('Emulation.getVisibleSize');7 console.log(dimensions);8 await browser.close();9})();10Output: { width: 800, height: 600 }

Full Screen

Using AI Code Generation

copy

Full Screen

1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const page = await browser.newPage();5 await page.setViewportSize({ width: 800, height: 600 });6 await page.screenshot({ path: 'example.png' });7 await browser.close();8})();9import { PlaywrightTestConfig } from '@playwright/test';10const config: PlaywrightTestConfig = {11 use: {12 viewport: { width: 800, height: 600 },13 },14};15export default config;16const { chromium } = require('playwright');17(async () => {18 const browser = await chromium.launch();19 const page = await browser.newPage();20 await page.setViewportSize({ width: 800, height: 600 });21 await page.screenshot({ path: 'example.png' });22 await browser.close();23})();24import { PlaywrightTestConfig } from '@playwright/test';25const config: PlaywrightTestConfig = {26 use: {27 viewport: { width: 800, height: 600 },28 },29};30export default config;31import { PlaywrightTestConfig } from '@playwright/test';32const config: PlaywrightTestConfig = {33 use: {34 viewport: { width: 800, height: 600 },

Full Screen

Using AI Code Generation

copy

Full Screen

1const { awaitViewportDimensions } = require('playwright/lib/server/browserContext');2const { chromium } = require('playwright');3(async () => {4 const browser = await chromium.launch();5 const context = await browser.newContext();6 const page = await context.newPage();7 const [width, height] = await awaitViewportDimensions.call(page);8 console.log(width, height);9 await browser.close();10})();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { test, expect } = require('@playwright/test');2test('test', async ({ page }) => {3 await page.setViewportSize({ width: 1280, height: 720 });4 await page.waitForLoadState();5 const dimensions = await page._delegate._mainFrameSession._client.send('Emulation.getVisibleSize');6 expect(dimensions).toEqual({ width: 1280, height: 720 });7});8const { test, expect } = require('@playwright/test');9test('test', async ({ page }) => {10 await page.setViewportSize({ width: 1280, height: 720 });11 await page.waitForLoadState();12 const dimensions = await page.viewportSize();13 expect(dimensions).toEqual({ width: 1280, height: 720 });14});

Full Screen

Using AI Code Generation

copy

Full Screen

1const playwright = require("playwright");2const { getViewportDimensions } = require("playwright/lib/server/supplements/recorder/recorderSupplement.js");3(async () => {4 const browser = await playwright["chromium"].launch();5 const context = await browser.newContext();6 const page = await context.newPage();7 const dimensions = await getViewportDimensions(page);8 console.log(dimensions);9 await browser.close();10})();11{ width: 1280, height: 800 }12const playwright = require("playwright");13const { getViewportDimensions } = require("playwright/lib/server/supplements/recorder/recorderSupplement.js");14(async () => {15 const browser = await playwright["chromium"].launch();16 const context = await browser.newContext();17 const page = await context.newPage();18 const dimensions = await getViewportDimensions(page);19 console.log(dimensions);20 await browser.close();21})();22const playwright = require("playwright");23const { getViewportDimensions } = require("playwright/lib/server/supplements/recorder/recorderSupplement.js");24(async () => {25 const browser = await playwright["chromium"].launch();26 const context = await browser.newContext();27 const page = await context.newPage();28 const dimensions = await getViewportDimensions(page);29 console.log(dimensions);30 await page.close();31 await browser.close();32})();33const playwright = require("playwright");34const { getViewportDimensions } = require("playwright/lib/server/supplements/recorder/recorderSupplement.js");35(async () => {36 const browser = await playwright["chromium"].launch();37 const context = await browser.newContext();38 const page = await context.newPage();39 await page.setViewportSize({ width: 1600, height: 900 });40 const dimensions = await getViewportDimensions(page);41 console.log(dimensions);

Full Screen

Using AI Code Generation

copy

Full Screen

1const playwright = require('playwright');2const { chromium } = playwright;3const { devices } = require('playwright');4const iPhone = devices['iPhone 6'];5(async () => {6 const browser = await chromium.launch();7 const context = await browser.newContext({8 viewport: { width: 800, height: 600 },9 });10 const page = await context.newPage();11 await page.waitForTimeout(3000);12 const dimensions = await page.mainFrame().awaitViewportDimensions();13 console.log(dimensions);14 await browser.close();15})();

Full Screen

Using AI Code Generation

copy

Full Screen

1import { Page } from 'playwright';2import { InternalAPI } from 'playwright-core/lib/internal';3export async function getViewportDimensions(page: Page) {4 const internalAPI = new InternalAPI(page);5 const { width, height } = await internalAPI.awaitViewportDimensions();6 return { width, height };7}8import { getViewportDimensions } from './test.js';9const { width, height } = await getViewportDimensions(page);10import { Page } from 'playwright';11import { InternalAPI } from 'playwright-core/lib/internal';12export async function getViewportDimensions(page: Page) {13 const internalAPI = new InternalAPI(page);14 const { width, height } = await internalAPI.awaitViewportDimensions();15 return { width, height };16}17import { getViewportDimensions } from './test.js';18const { width, height } = await getViewportDimensions(page);19import { Page } from 'playwright';20import { InternalAPI } from 'playwright-core/lib/internal';21export async function getViewportDimensions(page: Page) {22 const internalAPI = new InternalAPI(page);23 const { width, height } = await internalAPI.awaitViewportDimensions();24 return { width, height };25}26import { getViewportDimensions } from './test.js';27const { width, height } = await getViewportDimensions(page);28import { Page } from 'playwright';29import { InternalAPI } from 'playwright-core/lib/internal';30export async function getViewportDimensions(page: Page) {31 const internalAPI = new InternalAPI(page);32 const { width, height } = await internalAPI.awaitViewportDimensions();33 return { width, height };34}35import { getViewportDimensions } from './test.js';36const { width, height } = await getViewportDimensions(page);

Full Screen

Playwright tutorial

LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.

Chapters:

  1. What is Playwright : Playwright is comparatively new but has gained good popularity. Get to know some history of the Playwright with some interesting facts connected with it.
  2. How To Install Playwright : Learn in detail about what basic configuration and dependencies are required for installing Playwright and run a test. Get a step-by-step direction for installing the Playwright automation framework.
  3. Playwright Futuristic Features: Launched in 2020, Playwright gained huge popularity quickly because of some obliging features such as Playwright Test Generator and Inspector, Playwright Reporter, Playwright auto-waiting mechanism and etc. Read up on those features to master Playwright testing.
  4. What is Component Testing: Component testing in Playwright is a unique feature that allows a tester to test a single component of a web application without integrating them with other elements. Learn how to perform Component testing on the Playwright automation framework.
  5. Inputs And Buttons In Playwright: Every website has Input boxes and buttons; learn about testing inputs and buttons with different scenarios and examples.
  6. Functions and Selectors in Playwright: Learn how to launch the Chromium browser with Playwright. Also, gain a better understanding of some important functions like “BrowserContext,” which allows you to run multiple browser sessions, and “newPage” which interacts with a page.
  7. Handling Alerts and Dropdowns in Playwright : Playwright interact with different types of alerts and pop-ups, such as simple, confirmation, and prompt, and different types of dropdowns, such as single selector and multi-selector get your hands-on with handling alerts and dropdown in Playright testing.
  8. Playwright vs Puppeteer: Get to know about the difference between two testing frameworks and how they are different than one another, which browsers they support, and what features they provide.
  9. Run Playwright Tests on LambdaTest: Playwright testing with LambdaTest leverages test performance to the utmost. You can run multiple Playwright tests in Parallel with the LammbdaTest test cloud. Get a step-by-step guide to run your Playwright test on the LambdaTest platform.
  10. Playwright Python Tutorial: Playwright automation framework support all major languages such as Python, JavaScript, TypeScript, .NET and etc. However, there are various advantages to Python end-to-end testing with Playwright because of its versatile utility. Get the hang of Playwright python testing with this chapter.
  11. Playwright End To End Testing Tutorial: Get your hands on with Playwright end-to-end testing and learn to use some exciting features such as TraceViewer, Debugging, Networking, Component testing, Visual testing, and many more.
  12. Playwright Video Tutorial: Watch the video tutorials on Playwright testing from experts and get a consecutive in-depth explanation of Playwright automation testing.

Run Playwright Internal automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful