Best JavaScript code snippet using playwright-internal
uber-controller.js
Source:uber-controller.js  
...32													delay: 1000,33													timeout: 2000034												}) => {35	console.log(`Waiting for selector (${desc}): ${selector}`);36	await _screenshot(page, `click_before_wait_${desc}_${Date.now()}`);37	await page.waitForSelector(selector, {timeout: timeout});38	await _screenshot(page, `click_after_wait_${desc}_${Date.now()}`);39	console.log(`Selector found in page`);40	await page.click(selector);41	await _screenshot(page, `click_after_click_${desc}_${Date.now()}`);42	console.log(`Clicked selector. Now waiting ${delay}ms`);43	await page.waitFor(delay);44	await _screenshot(page, `click_after_second_wait_${desc}_${Date.now()}`);45	console.log(`Done waiting.`);46}47const _wait_for_function_and_perform_func = async (page,48												   wait_func,49												   wait_func_params,50												   exec_func = null,51												   exec_func_params = null,52 												   {53												 	   desc = "",54													   delay = 1000,55													   timeout = 2000056												   } =57												 	   {58													 	   desc: "",59														   delay: 1000,60														   timeout: 2000061													   }) => {62	console.log(`Waiting for function (${desc})`);63	await _screenshot(page, `before_wait_for_wait_func_${desc}_${Date.now()}`);64	await page.waitForFunction(wait_func, {timeout: timeout}, ...wait_func_params);65	await _screenshot(page, `after_wait_for_wait_func_${desc}_${Date.now()}`);66	if (!exec_func) {67		console.log("No exec function...returning.");68		return null;69	}70	const retVal = await page.evaluate(exec_func, ...exec_func_params);71	await _screenshot(page, `after_evaluate_exec_func_${desc}_${Date.now()}`);72	await page.waitFor(delay);73	await _screenshot(page, `after_wait_for_second_wait_for_wait_func_${desc}_${Date.now()}`);74	console.log(`Done waiting.`);75	return retVal;76}77const _wait_for_selector_and_select = async (page,78											 selector,79											 value,80											 {81												 desc = "",82												 delay = 1000,83												 timeout = 20000,84												 hideValue = false,85											 } =86												 {87													 desc: "",88													 delay: 1000,89													 timeout: 20000,90													 hideValue: false,91												 }) => {92	console.log(`Waiting for selector (${desc}): ${selector}`);93	await _screenshot(page, `select_before_wait_${desc}_${Date.now()}`);94	await page.waitForSelector(selector, {timeout: timeout});95	console.log(`Selector found in page`);96	await _screenshot(page, `select_after_wait_${desc}_${Date.now()}`);97	await page.select(selector, value);98	const redactedValue = hideValue ? "*******" : value;99	console.log(`Selected ${redactedValue} from dropdown. Now waiting ${delay}ms`);100	await _screenshot(page, `select_after_select_${desc}_${Date.now()}`);101	await page.waitFor(delay);102	await _screenshot(page, `select_after_second_wait_${desc}_${Date.now()}`);103	console.log(`Done waiting.`);104}105const _wait_for_selector_and_type = async (page,106										   selector,107										   value,108										   {109											   desc = "",110											   delay = 1000,111											   timeout = 10000,112											   hideValue = false,113										   } =114											   {115												   desc: "",116												   delay: 1000,117												   timeout: 10000,118												   hideValue: false,119											   }) => {120	console.log(`Waiting for selector (${desc}): ${selector}`);121	await _screenshot(page, `type_before_wait_${desc}_${Date.now()}`);122	await page.waitForSelector(selector, {timeout: timeout});123	console.log(`Selector found in page`);124	await _screenshot(page, `type_after_wait_${desc}_${Date.now()}`);125	await page.type(selector, value);126	const redactedValue = hideValue ? "*******" : value;127	await _screenshot(page, `type_after_type_${desc}_${Date.now()}`);128	console.log(`Typed ${redactedValue} into field. Now waiting ${delay}ms`);129	await page.waitFor(delay);130	await _screenshot(page, `type_after_second_wait_${desc}_${Date.now()}`);131	console.log(`Done waiting.`);132}133const _click_and_wait_ms = async (page, selector, ms) => {134	  await page.click(selector);135	  await page.waitFor(ms);136}137const _click_and_wait_ms_deprecated = (page, selector, ms) => Promise.all([138	  page.evaluate((selector) => document.querySelector(selector).click(), selector),139      page.waitFor(ms),140]);141const _wait_for_selector = async (page, selector, delay, timeout) => {142	await page.waitForSelector(selector, {timeout: timeout});143	await page.waitFor(delay);144}...indicator.js
Source:indicator.js  
1// vi: sts=2 sw=2 et2const Lang = imports.lang;3const Signals = imports.signals;4const St = imports.gi.St;5const Cogl = imports.gi.Cogl;6const Shell = imports.gi.Shell;7const Clutter = imports.gi.Clutter;8const PanelMenu = imports.ui.panelMenu;9const PopupMenu = imports.ui.popupMenu;10const Slider = imports.ui.slider;11const Gettext = imports.gettext.domain('gnome-shell-screenshot');12const _ = Gettext.gettext;13const ExtensionUtils = imports.misc.extensionUtils;14const Local = ExtensionUtils.getCurrentExtension();15const Config = Local.imports.config.exports;16const Convenience = Local.imports.convenience.exports;17const { dump } = Local.imports.dump.exports;18const DefaultIcon = 'camera-photo-symbolic';19const settings = Convenience.getSettings();20const CaptureDelayMenu = new Lang.Class({21  Name: 'CaptureDelayMenu',22  Extends: PopupMenu.PopupMenuSection,23  createScale: function () {24    let scale = [0];25    for (let p = 1; p < 4; p ++) {26      for (let x = 1; x <= 10; x += 1) {27        scale.push(x * Math.pow(10, p));28      }29    }30    return scale;31  },32  _init: function(control) {33    this.parent();34    this.scaleMS = this.createScale();35    this.delayValueMS = settings.get_int(Config.KeyCaptureDelay);36    this.slider = new Slider.Slider(this.scaleToSlider(this.delayValueMS));37    this.slider.connect('value-changed', this.onDragEnd.bind(this));38    this.sliderItem = new PopupMenu.PopupBaseMenuItem({ activate: false });39    this.sliderItem.actor.add(this.slider.actor, { expand: true });40    this.addMenuItem(this.sliderItem);41    this.delayInfoItem = new PopupMenu.PopupMenuItem(42      '', { activate: false, hover: false, can_focus: false }43    );44    this.addMenuItem(this.delayInfoItem)45    this.updateDelayInfo();46  },47  scaleToSlider: function (ms) {48    return this.scaleMS.findIndex((v) => v >= ms) / (this.scaleMS.length-1);49  },50  sliderToScale: function (value) {51    return this.scaleMS[(value * (this.scaleMS.length-1)) | 0];52  },53  onDragEnd: function(slider, value, property) {54    const newValue = this.sliderToScale(value);55    if (newValue !== this.delayValueMS) {56      this.delayValueMS = newValue;57      settings.set_int(Config.KeyCaptureDelay, newValue);58      this.updateDelayInfo();59    }60  },61  updateDelayInfo: function() {62    const v = this.delayValueMS;63    let text;64    if (v === 0) {65      text = _('No Capture Delay');66    } else if (v < 1000) {67      text = `${v}ms ` + _('Capture Delay');68    } else {69      text = `${v / 1000}s ` + _('Capture Delay');70    }71    this.delayInfoItem.label.text = text;72  }73});74const ScreenshotSection = new Lang.Class({75  Name: "ScreenshotTool.ScreenshotSection",76  _init: function (menu) {77    this._screenshot = null;78    this._image = new PopupMenu.PopupBaseMenuItem();79    this._image.actor.content_gravity =80      Clutter.ContentGravity.RESIZE_ASPECT;81    this._clear = new PopupMenu.PopupMenuItem(_('Clear'));82    this._copy = new PopupMenu.PopupMenuItem(_('Copy'));83    this._save = new PopupMenu.PopupMenuItem(_('Save As...'));84    this._image.connect('activate', this._onImage.bind(this));85    this._clear.connect('activate', this._onClear.bind(this));86    this._copy.connect('activate', this._onCopy.bind(this));87    this._save.connect('activate', this._onSave.bind(this));88    menu.addMenuItem(this._image);89    menu.addMenuItem(this._clear);90    menu.addMenuItem(this._copy);91    menu.addMenuItem(this._save);92    // IMGUR93    menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());94    this._imgurMenu = new PopupMenu.PopupSubMenuMenuItem(_('Imgur'), false);95    this._imgurUpload = new PopupMenu.PopupMenuItem(_('Upload'));96    this._imgurOpen = new PopupMenu.PopupMenuItem(_('Open Link'));97    this._imgurCopyLink = new PopupMenu.PopupMenuItem(_('Copy Link'));98    this._imgurDelete = new PopupMenu.PopupMenuItem(_('Delete'));99    this._imgurUpload.connect('activate', this._onImgurUpload.bind(this));100    this._imgurOpen.connect('activate', this._onImgurOpen.bind(this));101    this._imgurCopyLink.connect('activate', this._onImgurCopyLink.bind(this));102    this._imgurDelete.connect('activate', this._onImgurDelete.bind(this));103    this._imgurMenu.menu.addMenuItem(this._imgurUpload);104    this._imgurMenu.menu.addMenuItem(this._imgurOpen);105    this._imgurMenu.menu.addMenuItem(this._imgurCopyLink);106    this._imgurMenu.menu.addMenuItem(this._imgurDelete);107    menu.addMenuItem(this._imgurMenu);108    menu.connect("open-state-changed", () => {109      this._updateVisibility();110    });111    this._updateVisibility();112  },113  _updateVisibility: function () {114    let visible = !!this._screenshot;115    this._image.actor.visible = visible;116    this._clear.actor.visible = visible;117    this._copy.actor.visible = visible;118    this._save.actor.visible = visible;119    let imgurEnabled = settings.get_boolean(Config.KeyEnableUploadImgur);120    let imgurComplete =121        this._screenshot &&122        this._screenshot.imgurUpload &&123        this._screenshot.imgurUpload.responseData;124    this._imgurMenu.actor.visible =125      visible && imgurEnabled;126    this._imgurUpload.actor.visible =127      visible && imgurEnabled && !imgurComplete;128    this._imgurOpen.actor.visible =129      visible && imgurEnabled && imgurComplete;130    this._imgurCopyLink.actor.visible =131      visible && imgurEnabled && imgurComplete;132    this._imgurDelete.actor.visible =133      visible && imgurEnabled && imgurComplete;134  },135  _setImage: function (pixbuf) {136    let {width, height} = pixbuf;137    if (height == 0) {138      return;139    }140    let image = new Clutter.Image();141    let success = image.set_data(142      pixbuf.get_pixels(),143      pixbuf.get_has_alpha()144        ? Cogl.PixelFormat.RGBA_8888145        : Cogl.PixelFormat.RGB_888,146      width,147      height,148      pixbuf.get_rowstride()149    );150    if (!success) {151      throw Error("error creating Clutter.Image()");152    }153    this._image.actor.content = image;154    this._image.actor.height = 200;155  },156  setScreenshot: function (screenshot) {157    this._screenshot = screenshot;158    if (screenshot) {159      this._setImage(screenshot.gtkImage.get_pixbuf());160      this._screenshot.connect("imgur-upload", (obj, upload) => {161        upload.connect("done", (obj, data) => {162          this._updateVisibility();163        });164      });165    }166    this._updateVisibility();167  },168  _onImage: function () {169    this._screenshot.launchOpen();170  },171  _onClear: function () {172    this.setScreenshot(null);173  },174  _onCopy: function () {175    this._screenshot.copyClipboard();176  },177  _onSave: function () {178    this._screenshot.launchSave();179  },180  _onImgurUpload: function () {181    this._screenshot.imgurStartUpload();182  },183  _onImgurOpen: function () {184    this._screenshot.imgurOpenURL();185  },186  _onImgurCopyLink: function () {187    this._screenshot.imgurCopyURL();188  },189  _onImgurDelete: function () {190    this._screenshot.imgurDelete();191  }192})193const Indicator = new Lang.Class({194  Name: "ScreenshotTool.Indicator",195  Extends: PanelMenu.Button,196  _init: function (extension) {197    this.parent(null, Config.IndicatorName);198    this._extension = extension;199    this._signalSettings = [];200    this._icon = new St.Icon({201      icon_name: DefaultIcon,202      style_class: 'system-status-icon'203    });204    this.actor.add_actor(this._icon);205    this.actor.connect('button-press-event', this._onClick.bind(this));206    this._buildMenu();207  },208  _onClick: function (obj, evt) {209    // only override primary button behavior210    if (evt.get_button() !== Clutter.BUTTON_PRIMARY) {211      return;212    }213    let action = settings.get_string(Config.KeyClickAction);214    if (action === 'show-menu') {215      return;216    }217    this.menu.close();218    this._extension.onAction(action);219  },220  _buildMenu: function () {221    // These actions can be triggered via shortcut or popup menu222    const items = [223      ["select-area", _("Select Area")],224      ["select-window", _("Select Window")],225      ["select-desktop", _("Select Desktop")]226    ];227    items.forEach(([action, title]) => {228      let item = new PopupMenu.PopupMenuItem(title);229      item.connect(230        'activate', function (action) {231          this.menu.close();232          this._extension.onAction(action);233        }.bind(this, action)234      );235      this.menu.addMenuItem(item);236    })237    // Delay238    this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());239    this.menu.addMenuItem(new CaptureDelayMenu());240    this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());241    this._screenshotSection = new ScreenshotSection(this.menu);242    this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());243    // Settings can only be triggered via menu244    let settingsItem = new PopupMenu.PopupMenuItem(_('Settings'));245    settingsItem.connect('activate', () => {246      let appSys = Shell.AppSystem.get_default();247      let prefs = appSys.lookup_app('gnome-shell-extension-prefs.desktop');248      if (prefs.get_state() == prefs.SHELL_APP_STATE_RUNNING) {249        prefs.activate();250      } else {251        prefs.get_app_info().launch_uris(252          ['extension:///' + Local.metadata.uuid], null253        );254      }255    });256    this.menu.addMenuItem(settingsItem);257  },258  setScreenshot: function (screenshot) {259    this._screenshotSection.setScreenshot(screenshot);260  },261  destroy: function () {262    this.parent();263    this._signalSettings.forEach((signal) => {264      settings.disconnect(signal);265    });266  }267});268var exports = {269  Indicator...controller.js
Source:controller.js  
1/*2 * This file is part of the ZombieBox package.3 *4 * Copyright © 2015-2020, Interfaced5 *6 * For the full copyright and license information, please view the LICENSE7 * file that was distributed with this source code.8 */9import app from 'generated/app';10import {div} from 'zb/html';11import AbstractApplication from 'zb/abstract-application';12import IKeyHandler from 'zb/interfaces/i-key-handler';13import Key from 'zb/device/input/key';14import EventPublisher from 'zb/events/event-publisher';15import Layer from 'zb/layers/layer';16import IMarkupProvider from './i-markup-provider';17import ScreenShot from './screenshot';18import UI, {PositionDiff} from './ui';19/**20 * @implements {IKeyHandler}21 */22export default class Controller {23	/**24	 */25	constructor() {26		this._onChildLayerShown = this._onChildLayerShown.bind(this);27		this._onChildLayerHidden = this._onChildLayerHidden.bind(this);28		/**29		 * @type {UI}30		 * @protected31		 */32		this._ui = null;33		/**34		 * @type {number}35		 * @protected36		 */37		this._currentPosition = 0;38		/**39		 * Default value is '77177'40		 * @type {Array<Key>}41		 * @protected42		 */43		this._sequence = [44			Key.DIGIT_7,45			Key.DIGIT_7,46			Key.DIGIT_1,47			Key.DIGIT_7,48			Key.DIGIT_749		];50		/**51		 * @type {Array<string>}52		 * @protected53		 */54		this._screenshots = [];55		/**56		 * @type {ScreenShot}57		 * @protected58		 */59		this._screenShot = null;60		/**61		 * @type {Layer}62		 * @protected63		 */64		this._currentLayer = null;65		/**66		 * @type {boolean}67		 * @protected68		 */69		this._isVisible = false;70		/**71		 * @type {HTMLDivElement}72		 * @protected73		 */74		this._container = null;75		this._createUI();76		this._setViewState({77			x: 0,78			y: 0,79			opacity: 0.5,80			scale: false81		});82	}83	/**84	 * @override85	 */86	processKey(zbKey, event) {87		if (!this._isVisible) {88			const seq = this._sequence;89			this._currentPosition = this._currentPosition || 0;90			if (seq[this._currentPosition] !== zbKey) {91				this._currentPosition = 0;92			} else if (this._currentPosition === seq.length - 1) {93				this._currentPosition = 0;94				this.activate();95				return true;96			} else {97				this._currentPosition++;98			}99		} else {100			if (zbKey === Key.BACK) {101				this.deactivate();102				return true;103			}104			return this._ui.processKey(zbKey, event);105		}106		return false;107	}108	/**109	 * Show PP UI and handle keys to perform manipulations with screenshot110	 */111	activate() {112		this._isVisible = true;113		this._ui.show();114		this._screenShot.getContainer().style.display = 'block';115		// workaround for getting EVENT_AFTER_SHOW event on app start116		this._bindToLayer(app.getCurrentLayer());117		this._container.style.display = 'block';118	}119	/**120	 * Hide PP UI121	 */122	deactivate() {123		this._isVisible = false;124		this._ui.hide();125		this._screenShot.getContainer().style.display = 'none';126		this._container.style.display = 'none';127	}128	/**129	 * @param {AbstractApplication} app130	 */131	attachToApp(app) {132		this._getAppProperty(() => this._getAppBody(app), app, app.EVENT_DOM_READY)133			.then((appBody) => appBody.appendChild(this._container));134		this._getAppProperty(() => app.getLayerManager(), app, app.EVENT_DEVICE_READY)135			.then((lm) => {136				lm.on(lm.EVENT_AFTER_SHOW, (eventName, layer) =>137					this._bindToLayer(/** @type {Layer} */(layer)));138				this._bindToLayer(app.getCurrentLayer());139			});140	}141	/**142	 * @param {string|Array<string>} url143	 */144	setScreenShotUrl(url) {145		this._screenshots = url instanceof Array ? url : [url];146		this._renderScreenshot(this._screenshots[0]);147	}148	/**149	 * @param {Array<Key>} seq150	 */151	setKeySequence(seq) {152		this._sequence = seq;153		this._currentPosition = 0;154	}155	/**156	 * @param {string} url157	 * @protected158	 */159	_renderScreenshot(url) {160		this._screenShot.setSource(url);161		this._ui.renderScreenshotValue(url);162	}163	/**164	 * @protected165	 */166	_createUI() {167		this._createContainer();168		this._screenShot = new ScreenShot();169		this._container.appendChild(this._screenShot.getContainer());170		this._screenShot.getContainer().style.display = 'none';171		this._ui = new UI(this._container);172		this._ui.on(this._ui.EVENT_CHANGE_OPACITY, (eventName, changeDiff) => this._setViewState({173			opacity: this._screenShot.getOpacity() + changeDiff * OPACITY_STEP174		}));175		this._ui.on(this._ui.EVENT_INVERT, () => this._setViewState({176			invert: this._screenShot.isInverted()177		}));178		this._ui.on(this._ui.EVENT_CHANGE_POSITION, (eventName, positionChangeDiff) => {179			positionChangeDiff = /** @type {PositionDiff} */ (positionChangeDiff);180			const position = this._screenShot.getPosition();181			const step = POSITION_STEP;182			if (positionChangeDiff.x) {183				position.x += step * positionChangeDiff.x;184			}185			if (positionChangeDiff.y) {186				position.y += step * positionChangeDiff.y;187			}188			this._setViewState({189				x: position.x,190				y: position.y191			});192		});193		this._ui.on(this._ui.EVENT_NEXT_SCREENSHOT, () => {194			if (this._screenshots.length > 1) {195				let nextIndex = this._screenshots.indexOf(this._screenShot.getSource()) + 1;196				if (nextIndex >= this._screenshots.length) {197					nextIndex = 0;198				}199				this._renderScreenshot(this._screenshots[nextIndex]);200			}201		});202		this._ui.on(this._ui.EVENT_TOGGLE, () => {203			const containerStyle = this._container.style;204			this._screenShot.getContainer().style.display = containerStyle.display === 'none' ? 'block' : 'none';205		});206		this._ui.on(this._ui.EVENT_TOGGLE_SCALE, () => this._setViewState({207			scale: this._screenShot.isScaled()208		}));209	}210	/**211	 * @protected212	 */213	_createContainer() {214		this._container = div();215		const containerStyle = this._container.style;216		containerStyle.position = 'absolute';217		containerStyle.top = '0';218		containerStyle.left = '0';219		containerStyle.width = '100%';220		containerStyle.height = '100%';221		containerStyle.zIndex = '1000';222		containerStyle.display = 'none';223		containerStyle.pointerEvents = 'none';224	}225	/**226	 * @param {{227	 *     x: (number|undefined),228	 *     y: (number|undefined),229	 *     opacity: (number|undefined),230	 *     invert: (boolean|undefined),231	 *     scale: (boolean|undefined)232	 * }} state233	 * @protected234	 */235	_setViewState(state) {236		if (state.x !== undefined || state.y !== undefined) {237			const position = {238				x: state.x !== undefined ? state.x : this._screenShot.getPosition().x,239				y: state.y !== undefined ? state.y : this._screenShot.getPosition().y240			};241			this._screenShot.setPosition(position.x, position.y);242			this._ui.renderPositionValue(position.x, position.y);243		}244		if (state.opacity !== undefined) {245			state.opacity = this._screenShot.setOpacity(state.opacity);246			this._ui.renderOpacityValue(state.opacity);247		}248		if (state.scale !== undefined) {249			this._screenShot.setScale(state.scale);250			this._ui.renderScaleValue(state.scale);251		}252		if (state.invert !== undefined) {253			this._screenShot.setInvert(state.invert);254			this._ui.renderInvertValue(state.invert);255		}256	}257	/**258	 * @param {string} eventName259	 * @param {Layer} layer260	 * @protected261	 */262	_onChildLayerShown(eventName, layer) {263		this._showScreenshotsFromLayer(layer);264	}265	/**266	 * @protected267	 */268	_onChildLayerHidden() {269		this._showScreenshotsFromLayer(this._currentLayer);270	}271	/**272	 * @param {Layer} layer273	 * @protected274	 */275	_bindToLayer(layer) {276		if (this._currentLayer) {277			this._currentLayer.off(this._currentLayer.EVENT_CHILD_LAYER_SHOWN, this._onChildLayerShown);278			this._currentLayer.off(this._currentLayer.EVENT_CHILD_LAYER_HIDDEN, this._onChildLayerHidden);279		}280		this._currentLayer = layer;281		if (layer) {282			layer.on(layer.EVENT_CHILD_LAYER_SHOWN, this._onChildLayerShown);283			layer.on(layer.EVENT_CHILD_LAYER_HIDDEN, this._onChildLayerHidden);284		}285		this._showScreenshotsFromLayer(layer);286	}287	/**288	 * @param {Layer} layer289	 * @protected290	 */291	_showScreenshotsFromLayer(layer) {292		const topLayer = layer ? layer.getTopChildLayer() || layer : null;293		const screenshots = this._getScreenShotsFromLayer(topLayer);294		if (screenshots && screenshots.length) {295			this.setScreenShotUrl(screenshots);296		} else {297			this.setScreenShotUrl('');298		}299	}300	/**301	 * @param {Layer|IMarkupProvider} layer302	 * @return {?Array<string>}303	 * @protected304	 */305	_getScreenShotsFromLayer(layer) {306		if (layer && typeof layer.getMarkupImage === 'function') {307			const mp = /** @type {IMarkupProvider} */ (layer);308			const screenshots = mp.getMarkupImage();309			return screenshots instanceof Array ? screenshots : [screenshots];310		}311		return null;312	}313	/**314	 * @suppress {accessControls}315	 * @param {AbstractApplication} app316	 * @return {HTMLElement}317	 * @protected318	 */319	_getAppBody(app) {320		return app._body;321	}322	/**323	 * @param {function(): *} getter324	 * @param {EventPublisher} obj325	 * @param {string} event326	 * @return {Promise}327	 * @protected328	 */329	_getAppProperty(getter, obj, event) {330		return new Promise((resolve) => {331			const result = getter();332			if (result) {333				resolve(result);334			} else {335				obj.on(event, () => resolve(getter()));336			}337		});338	}339}340/**341 * @const {number}342 */343export const OPACITY_STEP = 0.05;344/**345 * @const {number}346 */...screenshotcontrols.js
Source:screenshotcontrols.js  
...123    {124      this._screenshot = window.views.screenshot;125    }126    this._screenshot._take_screenshot = true;127    this._screenshot.update_screenshot(event.shiftKey);128  }.bind(this);129  this._handlers['screenshot-zoom'] = function(event, target)130  {131    if (!this._screenshot)132    {133      this._screenshot = window.views.screenshot;134    }135    this._scale = parseInt(event.target.value);136    this._screenshot.zoom_center(this._scale);137    this._ruler.scale = this._scale;138  }.bind(this);139  this._handlers['screenshot-sample-size'] = function(event, target)140  {141    if (!this._screenshot)...notifications.js
Source:notifications.js  
1// vi: sts=2 sw=2 et2const Lang = imports.lang;3const Signals = imports.signals;4const St = imports.gi.St;5const Gio = imports.gi.Gio;6const Gtk = imports.gi.Gtk;7const GdkPixbuf = imports.gi.GdkPixbuf;8const Main = imports.ui.main;9const MessageTray = imports.ui.messageTray;10const Gettext = imports.gettext.domain('gnome-shell-screenshot');11const _ = Gettext.gettext;12const ExtensionUtils = imports.misc.extensionUtils;13const Local = ExtensionUtils.getCurrentExtension();14const Path = Local.imports.path.exports;15const {dump} = Local.imports.dump.exports;16const Config = Local.imports.config.exports;17const Clipboard = Local.imports.clipboard.exports;18const Thumbnail = Local.imports.thumbnail.exports;19const Convenience = Local.imports.convenience.exports;20const NotificationIcon = 'camera-photo-symbolic';21const NotificationSourceName = 'Screenshot Tool';22const ICON_SIZE = 64;23const settings = Convenience.getSettings();24const getSource = () => {25  let source = new MessageTray.Source(26    NotificationSourceName, NotificationIcon27  );28  Main.messageTray.add(source);29  return source;30}31const Notification = new Lang.Class({32  Name: "ScreenshotTool.Notification",33  Extends: MessageTray.Notification,34  _title: function () {35    return _("New Screenshot");36  },37  _banner: function ({gtkImage}) {38    let {width, height} = gtkImage.get_pixbuf();39    let banner = _("Size:") + " " + width + "x" + height + ".";40    return banner;41  },42  _init: function (source, screenshot) {43    this.parent(44      source,45      this._title(),46      this._banner(screenshot),47      { gicon: Thumbnail.getIcon(screenshot.srcFile.get_path()) }48    );49    this.connect("activated", this._onActivated.bind(this));50    // makes banner expand on hover51    this.setForFeedback(true);52    this._screenshot = screenshot;53  },54  createBanner: function() {55    let b = this.parent();56    b._iconBin.child.icon_size = ICON_SIZE;57    b.addAction(_("Copy"), this._onCopy.bind(this));58    b.addAction(_("Save"), this._onSave.bind(this));59    if (settings.get_boolean(Config.KeyEnableUploadImgur)) {60      if (settings.get_boolean(Config.KeyImgurAutoUpload)) {61        b.addAction(_("Uploading To Imgur..."), () => { /* noop */ });62      } else {63        b.addAction(_("Upload To Imgur"), this._onUpload.bind(this));64      }65    }66    return b;67  },68  _onActivated: function () {69    this._screenshot.launchOpen();70  },71  _onCopy: function () {72    this._screenshot.copyClipboard();73  },74  _onSave: function () {75    this._screenshot.launchSave();76  },77  _onUpload: function () {78    this._screenshot.imgurStartUpload();79  }80});81Signals.addSignalMethods(Notification.prototype);82const ErrorNotification = new Lang.Class({83  Name: "ScreenshotTool.ErrorNotification",84  Extends: MessageTray.Notification,85  _init: function (source, message) {86    this.parent(87      source,88      _("Error"),89      String(message),90      { secondaryGIcon: new Gio.ThemedIcon({name: 'dialog-error'}) }91    );92  }93});94Signals.addSignalMethods(ErrorNotification.prototype);95const ImgurNotification = new Lang.Class({96  Name: "ScreenshotTool.ImgurNotification",97  Extends: MessageTray.Notification,98  _init: function (source, screenshot) {99    this.parent(source, _("Imgur Upload"));100    this.setForFeedback(true);101    this.setResident(true);102    this.connect("activated", this._onActivated.bind(this));103    this._screenshot = screenshot;104    this._upload = screenshot.imgurUpload;105    this._upload.connect("progress", (obj, bytes, total) => {106      this.update(107          _("Imgur Upload"),108          '' + Math.floor(100 * (bytes / total)) + '%'109      );110    });111    this._upload.connect("error", (obj, msg) => {112      this.update(_("Imgur Upload Failed"), msg);113    });114    this._upload.connect("done", () => {115      this.update(116        _("Imgur Upload Successful"), this._upload.responseData.link117      );118      this._updateCopyButton();119    });120  },121  _updateCopyButton: function () {122    if (!this._copyButton) {123      return;124    }125    this._copyButton.visible = this._screenshot.isImgurUploadComplete();126  },127  createBanner: function() {128    let b = this.parent();129    this._copyButton = b.addAction(_("Copy Link"), this._onCopy.bind(this));130    this._updateCopyButton();131    return b;132  },133  _onActivated: function () {134    if (this._screenshot.isImgurUploadComplete()) {135      this._screenshot.imgurOpenURL();136    } else {137      this._upload.connect("done", () => {138        this._screenshot.imgurOpenURL();139      });140    }141  },142  _onCopy: function () {143    this._screenshot.imgurCopyURL();144  },145});146const notifyScreenshot = (screenshot) => {147  let source = getSource();148  let notification = new Notification(source, screenshot);149  source.notify(notification);150}151const notifyError = (message) => {152  let source = getSource();153  let notification = new ErrorNotification(source, message);154  source.notify(notification);155}156const notifyImgurUpload = (screenshot) => {157  let source = getSource();158  let notification = new ImgurNotification(source, screenshot);159  source.notify(notification);160}161var exports = {162  notifyError,163  notifyScreenshot,164  notifyImgurUpload...screencast.js
Source:screencast.js  
1import optimize from './optimize.js';2import patch from './patch.js';34/** @typedef {{ ({ x: number; y: number; width: number; height: number; }) => Buffer; }} Crop */5/** @typedef {{ stamp: Date; buffer: Buffer; width: number; height: number; format: string; crop: Crop; }} Screenshot */67export default async function* screencast(/** @type {() => AsyncGenerator<Screenshot>} */ screenshots) {8  let frame = 0;910  /** @type {Date} */11  let _stamp;1213  /** @type {Screenshot} */14  let _screenshot;1516  // Allow passing in both a generator function and a generator object17  if (typeof screenshots === 'function') {18    screenshots = screenshots();19  }2021  for await (const screenshot of screenshots) {22    // Use worker communication for crop because the crop screenshot function itself cannot be marshalled to the worker23    if (!screenshot.crop) {24      screenshot.crop = makeWorkerCrop(screenshot.buffer, screenshot.width, screenshot.height);25    }2627    const { stamp, width, height, format, buffer, crop } = screenshot;2829    // Write header and poster on initial screenshot30    if (_stamp === undefined) {31      yield `<svg width="${width}" height="${height}" xmlns="http://www.w3.org/2000/svg">\n`;32      yield `<image width="${width}" height="${height}" href="data:image/${format};base64,${(await crop()).toString('base64')}"/>\n`;33      yield `<style>\nimage[class] { visibility: hidden; }\n@keyframes _ { to { visibility: visible; } }\n</style>\n`;3435      _stamp = stamp;36      _screenshot = screenshot;37      continue;38    }3940    // Ensure size remains constant among the screenshots41    if (width !== _screenshot.width || height !== _screenshot.height) {42      throw new Error(`Screenshot size ${width}Ã${height} differs from baseline ${_screenshot.width}Ã${_screenshot.height}.`);43    }4445    // Ensure stamp remains chronological among the screenshots46    if (stamp <= _stamp) {47      throw new Error(`Screenshot stamp ${stamp} is not chronological with respect to baseline ${_stamp}.`);48    }4950    const patches = await optimize(patch(width, height, buffer, _screenshot.buffer), crop);51    if (patches.length > 0) {52      yield `<style>._${frame} { animation: _ 0ms ${~~(stamp - _stamp)}ms forwards; }</style>\n`;5354      for (const patch of patches) {55        const { x, y, width, height } = patch;56        const buffer = await crop(patch);57        yield `<image class="_${frame}" x="${x}" y="${y}" width="${width}" height="${height}" href="data:image/${format};base64,${buffer.toString('base64')}"/>\n`;58      }5960      frame++;61    }6263    _screenshot = screenshot;64  }6566  yield '</svg>\n';67}6869const crops = {};7071function makeWorkerCrop(/** @type {Buffer} */ buffer, /** @type {number} */ width, /** @type {number} */ height) {72  return function workerCrop(/** @type {{ x: number; y: number; width: number; height: number; }} */ patch) {73    const id = Math.random();74    crops[id] = defer();75    // Issue crop request76    globalThis.worker_threads.parentPort.postMessage({ crop: true, id, buffer, width, height, patch });77    return crops[id].promise;78  }79}8081void async function () {82  try {83    // Import conditionally to make runnable in the browser84    globalThis.worker_threads = await import('worker_threads');85    // Abort self-start in case `screencast` is not used in worker context86    if (worker_threads.isMainThread) {87      return;88    }8990    const status = {};91    for await (const buffer of screencast(cache(status))) {92      worker_threads.parentPort.postMessage(buffer);93    }9495    worker_threads.parentPort.postMessage(null);96  }97  catch (error) {98    // TODO: Add support for web workers to have a web browser parallel feature99    console.log('Not attempting worker check - running in browser');100  }101}()102103// TODO: Move the non-worker cache mechanism within `screencast.js` as well104async function* cache(status) {105  const messages = [];106  let done = defer();107108  globalThis.worker_threads.parentPort.addEventListener('message', event => {109    if (event.data === null) {110      done.resolve(true);111      return;112    }113114    // Handle crop response115    if (event.data.crop === true) {116      // Access the buffer.buffer property to go Uint8Array -> Buffer117      crops[event.data.id].resolve(Buffer.from(event.data.buffer));118      delete crops[event.data.id];119      return;120    }121122    messages.push(event.data);123    status.overhead = messages.length;124    done.resolve(false);125    done = defer();126  });127128  while (messages.length > 0 || !await done.promise) {129    if (messages.length > 0) {130      yield messages.shift();131    }132  }133}134135function defer() {136  let resolve;137  let reject;138  const promise = new Promise((_resolve, _reject) => {139    resolve = _resolve;140    reject = _reject;141  });142143  return { resolve, reject, promise };
...Request_Image.js
Source:Request_Image.js  
1const Request_Base = require( './Request_Base.js' );2module.exports = class Request_Image extends Request_Base {3  bodyWidth;4  bodyHeight;5  /**6   * Get scroll width and height of the rendered page and set viewport.7   * @returns {Promise<void>}8   * @private9   */10  async _initialize() {11    this.bodyWidth   = await this.page.evaluate( () => document.body.scrollWidth );12    this.bodyHeight  = await this.page.evaluate( () => document.body.scrollHeight );13    this.req.logger.debug( 'Page document dimensions: ' + this.bodyWidth.toString() + ', ' + this.bodyHeight.toString() );14    await this.page.setViewport( {15      width:  this.bodyWidth,16      height: this.bodyHeight17    } );18  }19  async do() {20    let _screenshot = this._getScreenShotOptions( this.req, this.bodyWidth, this.bodyHeight );21    this.req.logger.debug( 'Screenshot Options', _screenshot );22    if ( ! this.req.query.block.types.includes( 'script' ) ) {23      await this._autoScroll( this.page );24    }25    let _img = await this.page.screenshot( _screenshot );26    if ( 'base64' !== _screenshot.encoding ) {27      this.res.writeHead( 200, { 'Content-Type': 'image/' + this.type } );28      this.res.end( _img, 'binary' );29      return;30    }31    this.res.writeHead( 200, { 'Content-Type': 'text/plain' } );32    this.res.end( _img, 'utf8' );33  }34    _getScreenShotOptions( req, bodyWidth, bodyHeight ) {35      let _screenshot = req.query.screenshot36      delete _screenshot.fullPage;37      delete _screenshot.path;38      _screenshot.type = this.type;39      if ( 'undefined' !== typeof _screenshot.quality ) {40        _screenshot.quality        = parseInt( _screenshot.quality );41        if ( isNaN( _screenshot.quality ) ) {42          delete _screenshot.quality43        }44      }45      if ( 'undefined' !== typeof _screenshot.omitBackground ) {46        _screenshot.omitBackground = Boolean( _screenshot.omitBackground );47      }48      if ( 'base64' !== _screenshot.encoding ) {49        delete _screenshot.encoding;50      }51      _screenshot.clip.width  = parseInt( this.req.query.screenshot.clip.width );52      _screenshot.clip.height = parseInt( this.req.query.screenshot.clip.height );53      _screenshot.clip.x      = parseInt( this.req.query.screenshot.clip.x ) || 0;54      _screenshot.clip.y      = parseInt( this.req.query.screenshot.clip.y ) || 0;55      if ( ! ( req.query.screenshot.clip.width || req.query.screenshot.clip.height || req.query.screenshot.clip.x || req.query.screenshot.clip.y ) ) {56        _screenshot.fullPage = true;57        delete _screenshot.clip;58        return _screenshot;59      }60      let _ssx  = _screenshot.clip.x;61      let _ssy  = _screenshot.clip.y;62      let _maxW = bodyWidth - _ssx;63      let _maxH = bodyHeight - _ssy;64      let _ssw  = _screenshot.clip.width || _maxW;65      _ssw = Math.min( _ssw, _maxW );66      let _ssh  = _screenshot.clip.height || _maxH;67      _ssh = Math.min( _ssh, _maxH );68      // req.debug.log( 'screenshot height calc', _ssh, _maxH, 'body height', bodyHeight, 'y offset', _ssy, 'document height' );69      this.req.logger.debug( 'Screenshot Dimension', {70        x: _ssx,71        y: _ssy,72        w: _ssw,73        h: _ssh,74      } );75      _screenshot.clip = {76        x: _ssx,77        y: _ssy,78        width: _ssw,79        height: _ssh,80      }81      return _screenshot;82    };83  /**84   * @see https://stackoverflow.com/a/5352798485   * @param page86   * @returns {Promise<void>}87   */88  async _autoScroll(page){89    await page.evaluate(async () => {90      await new Promise((resolve, reject) => {91        let totalHeight = 0;92        let distance = 100;93        let timer = setInterval(() => {94          let scrollHeight = document.body.scrollHeight;95          window.scrollBy(0, distance);96          totalHeight += distance;97          if(totalHeight >= scrollHeight){98              clearInterval(timer);99              resolve();100          }101        }, 100);102      });103    });104  }...generate_pdf.js
Source:generate_pdf.js  
1"use strict";2Object.defineProperty(exports, "__esModule", {3  value: true4});5exports.generatePdfObservable = generatePdfObservable;6var _lodash = require("lodash");7var _operators = require("rxjs/operators");8var _pdf = require("../../common/pdf");9var _tracker = require("./tracker");10/*11 * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one12 * or more contributor license agreements. Licensed under the Elastic License13 * 2.0; you may not use this file except in compliance with the Elastic License14 * 2.0.15 */16const getTimeRange = urlScreenshots => {17  const grouped = (0, _lodash.groupBy)(urlScreenshots.map(({18    timeRange19  }) => timeRange));20  const values = Object.values(grouped);21  if (values.length === 1) {22    return values[0][0];23  }24  return null;25};26function generatePdfObservable(reporting, logger, title, options, logo) {27  const tracker = (0, _tracker.getTracker)();28  tracker.startScreenshots();29  return reporting.getScreenshots(options).pipe((0, _operators.mergeMap)(async ({30    layout,31    metrics$,32    results33  }) => {34    metrics$.subscribe(({35      cpu,36      memory37    }) => {38      tracker.setCpuUsage(cpu);39      tracker.setMemoryUsage(memory);40    });41    tracker.endScreenshots();42    tracker.startSetup();43    const pdfOutput = new _pdf.PdfMaker(layout, logo);44    if (title) {45      const timeRange = getTimeRange(results);46      title += timeRange ? ` - ${timeRange}` : '';47      pdfOutput.setTitle(title);48    }49    tracker.endSetup();50    results.forEach(r => {51      r.screenshots.forEach(screenshot => {52        var _screenshot$title, _screenshot$descripti;53        logger.debug(`Adding image to PDF. Image size: ${screenshot.data.byteLength}`); // prettier-ignore54        tracker.startAddImage();55        tracker.endAddImage();56        pdfOutput.addImage(screenshot.data, {57          title: (_screenshot$title = screenshot.title) !== null && _screenshot$title !== void 0 ? _screenshot$title : undefined,58          description: (_screenshot$descripti = screenshot.description) !== null && _screenshot$descripti !== void 0 ? _screenshot$descripti : undefined59        });60      });61    });62    let buffer = null;63    try {64      var _buffer$byteLength, _buffer;65      tracker.startCompile();66      logger.info(`Compiling PDF using "${layout.id}" layout...`);67      pdfOutput.generate();68      tracker.endCompile();69      tracker.startGetBuffer();70      logger.debug(`Generating PDF Buffer...`);71      buffer = await pdfOutput.getBuffer();72      const byteLength = (_buffer$byteLength = (_buffer = buffer) === null || _buffer === void 0 ? void 0 : _buffer.byteLength) !== null && _buffer$byteLength !== void 0 ? _buffer$byteLength : 0;73      logger.debug(`PDF buffer byte length: ${byteLength}`);74      tracker.setByteLength(byteLength);75      tracker.endGetBuffer();76    } catch (err) {77      logger.error(`Could not generate the PDF buffer!`);78      logger.error(err);79    }80    tracker.end();81    return {82      buffer,83      warnings: results.reduce((found, current) => {84        if (current.error) {85          found.push(current.error.message);86        }87        if (current.renderErrors) {88          found.push(...current.renderErrors);89        }90        return found;91      }, [])92    };93  }));...Using AI Code Generation
1const fs = require('fs');2const { chromium } = require('playwright');3(async () => {4  const browser = await chromium.launch({ headless: false });5  const context = await browser.newContext();6  const page = await context.newPage();7  const screenshot = await page._screenshot();8  fs.writeFileSync('screenshot.png', screenshot);9  await browser.close();10})();11const fs = require('fs');12const { chromium } = require('playwright');13(async () => {14  const browser = await chromium.launch({ headless: false });15  const context = await browser.newContext();16  const page = await context.newPage();17  await page.setViewportSize({ width: 800, height: 600 });18  const screenshot = await page._screenshot({ fullPage: true });19  fs.writeFileSync('screenshot.png', screenshot);20  await browser.close();21})();Using AI Code Generation
1const path = require('path');2const { chromium } = require('playwright');3(async () => {4  const browser = await chromium.launch({ headless: false });5  const context = await browser.newContext();6  await page._screenshot({7    path: path.join(__dirname, 'screenshot.png'),8  });9  await browser.close();10})();11{12  "scripts": {13  },14  "dependencies": {15  }16}17const path = require('path');18const { chromium } = require('playwright');19(async () => {20  const browser = await chromium.launch({ headless: false });21  const context = await browser.newContext();22  await page.screenshot({23    path: path.join(__dirname, 'screenshot.png'),24  });25  await browser.close();26})();27const path = require('path');28const puppeteer = require('puppeteer');29(async () => {30  const browser = await puppeteer.launch({ headless: false });31  const page = await browser.newPage();Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3  const browser = await chromium.launch();4  const page = await browser.newPage();5  await page.screenshot({ path: 'example.png' });6  await browser.close();7})();8const { chromium } = require(require.resolve('playwright', { paths: [process.cwd()] }));9(async () => {10  const browser = await chromium.launch();11  const page = await browser.newPage();12  await page.screenshot({ path: 'example.png' });13  await browser.close();14})();15The require.resolve() function takes two parameters:16const utils = require(require.resolve('./utils', { paths: [process.cwd()] }));17utils.printHello();Using AI Code Generation
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  await page._screenshot({ path: 'example.png' });7  await browser.close();8})();Using AI Code Generation
1const { _screenshot } = require('playwright/lib/server/chromium/crPage');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 screenshot = await _screenshot.call(page, {8  });9  require('fs').writeFileSync('screenshot.png', screenshot);10  await browser.close();11})();12You can also save the screenshot using the page.screenshot() method:13const { chromium } = require('playwright');14(async () => {15  const browser = await chromium.launch();16  const context = await browser.newContext();17  const page = await context.newPage();18  await page.screenshot({ path: 'screenshot.png' });19  await browser.close();20})();21You can get the browser context of a page using the page.context() method:22const { chromium } = require('playwright');23(async () => {24  const browser = await chromium.launch();25  const context = await browser.newContext();26  const page = await context.newPage();27  const browserContext = page.context();28  await browser.close();29})();30You can get the browser of a page using the page.browser() method:31const { chromium } = require('playwright');32(async () => {33  const browser = await chromium.launch();34  const context = await browser.newContext();35  const page = await context.newPage();36  const browserInstance = page.browser();37  await browser.close();38})();39You can get the frame of a page using the page.mainFrame() method:40const { chromium } = require('playwright');41(async () => {42  const browser = await chromium.launch();43  const context = await browser.newContext();44  const page = await context.newPage();Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3    const browser = await chromium.launch();4    const page = await browser.newPage();5    const screenshot = await page._screenshot();6    console.log(screenshot);7    await browser.close();8})();9    at CDPSession.send (C:\Users\Neha\Desktop\New folder\New folder10    at Page._screenshot (C:\Users\Neha\Desktop\New folder\New folder11    at processTicksAndRejections (internal/process/task_queues.js:97:5)12    at async Object.<anonymous> (C:\Users\Neha\Desktop\New folder\New folder13    at async Promise.all (index 0)14    at async Promise.all (index 0)15    at async Page.<anonymous> (C:\Users\Neha\Desktop\New folder\New folder16    at async Promise.all (index 0)17    at async Page.<anonymous> (C:\Users\Neha\Desktop\New folder\New folderUsing AI Code Generation
1const playwright = require('playwright');2const { _screenshot } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');3(async () => {4  const browser = await playwright.chromium.launch({ headless: false });5  const context = await browser.newContext();6  const page = await context.newPage();7  const screenshot = await _screenshot(page, { clip: { x: 0, y: 0, width: 100, height: 100 } });8  console.log(screenshot);9  await browser.close();10})();11const playwright = require('playwright');12const { _screenshot } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');13(async () => {14  const browser = await playwright.chromium.launch({ headless: false });15  const context = await browser.newContext();16  const page = await context.newPage();17  const screenshot = await _screenshot(page, { clip: { x: 0, y: 0, width: 100, height: 100 } });18  console.log(screenshot);19  await browser.close();20})();21const playwright = require('playwright');22const { _screenshot } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');23(async () => {24  const browser = await playwright.chromium.launch({ headless: false });25  const context = await browser.newContext();26  const page = await context.newPage();27  const screenshot = await _screenshot(page, { clip: { x: 0, y: 0, width: 100, height: 100 } });28  console.log(screenshot);29  await browser.close();30})();31const playwright = require('playwright');32const { _screenshot } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');33(async () => {34  const browser = await playwright.chromium.launch({ headless: false });Using AI Code Generation
1const { _screenshot } = require('playwright/lib/server/chromium/crBrowser');2(async () => {3    const browser = await chromium.launch({4    });5    const page = await browser.newPage();6    await page.screenshot({ path: 'google.png' });7    await browser.close();8})();9(async () => {10    const browser = await chromium.launch({11    });12    const page = await browser.newPage();13    const screenshot = await _screenshot.call(page, { type: 'png', fullPage:Using AI Code Generation
1const fs = require('fs');2const { chromium } = require('playwright');3(async () => {4  const browser = await chromium.launch({5  });6  const context = await browser.newContext();7  const page = await context.newPage();8  const screenshot = await page._screenshot();9  fs.writeFileSync('screenshot.png', screenshot);10  await browser.close();11})();12const fs = require('fs');13const { chromium } = require('playwright');14(async () => {15  const browser = await chromium.launch({16  });17  const context = await browser.newContext();18  const page = await context.newPage();19  const screenshot = fs.readFileSync('screenshot.png');20  await page._screenshot({ path: 'screenshot2.png', buffer: screenshot });21  await browser.close();22})();23In the above code, we have imported fs module to write the screenshot buffer to a fileLambdaTest’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.
Get 100 minutes of automation test minutes FREE!!
