How to use setWindowBounds method in Playwright Internal

Best JavaScript code snippet using playwright-internal

Run Playwright Internal automation tests on LambdaTest cloud grid

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

electronUtil.js

Source: electronUtil.js Github

copy
1const { INIT_WINDOW_STYLE } = require('../../com-constant')
2
3// const { doubced } = require('../../com-function')
4function setWindowBounds(mainWindow, data) {
5  mainWindow.setSize(data.width, data.height)
6
7  if (data.x === data.y && data.x === 'center') {
8    mainWindow.center()
9  } else if (data.x != null && data.y != null) {
10    mainWindow.setPosition(data.x, data.y)
11  }
12}
13
14exports.setWindowBounds = setWindowBounds
15
16exports.setMoyuModeData = function (mainWin, data = {}) {
17  setWindowBounds(mainWin, data)
18  mainWin.setAlwaysOnTop(data.isTop, 'screen-saver')
19  mainWin.setIgnoreMouseEvents(data.isTransparent)
20}
21
22function winScreen(win) {
23  let isFullScreen = false
24  let prevxy = {
25    // width:
26    ...INIT_WINDOW_STYLE,
27    x: 'center',
28    y: 'center',
29  }
30  win.on('enter-full-screen', () => {
31    // isFullScreen = true
32    setPrevdata()
33  })
34  /* const doubcedMoved = doubced(setPrevxy, 500)
35  win.on('move', () => {
36    // isFullScreen = true
37    doubcedMoved()
38  }) */
39  function setPrevxy() {
40    const [x, y] = win.getPosition()
41    prevxy.x = x
42    prevxy.y = y
43    console.log('setPrevxy', prevxy)
44  }
45  function getPosi() {
46    var data = win.getBounds()
47    const [x, y] = win.getPosition()
48    data.x = x
49    data.y = y
50    return data
51  }
52  function setPrevdata() {
53    prevxy = getPosi()
54    console.log('setPrevdata', prevxy)
55    return prevxy
56  }
57  /* win.on('blur', (a, b) => {
58    console.log('blur', win.getBounds())
59  }) */
60  function toggleAddSize(data) {
61    let isAdd = false
62
63    return {
64      isAdded() {
65        return isAdd
66      },
67      hide() {
68        if (!isAdd) {
69          return
70        }
71        isAdd = false
72        const dat = getPosi()
73        // restore()
74        setWindowBounds(win, {
75          width: dat.width - (data.width || 0),
76          height: dat.height - (data.height || 0),
77        })
78      },
79      show(letd) {
80        if (isAdd) {
81          return
82        }
83        isAdd = true
84        data = letd || data
85        const { width, height } = setPrevdata()
86        setWindowBounds(win, {
87          width: width + (data.width || 0),
88          height: height + (data.height || 0),
89        })
90      },
91      toggle(data) {
92        if (isAdd) {
93          this.hide()
94        } else {
95          this.show(data)
96        }
97        return isAdd
98      },
99    }
100  }
101  function toFullScreen() {
102    // 透明化后,这里获取的是全屏的信息
103    // console.log(win.getBounds())
104    /* prevxy = win.getBounds()
105    const [x, y] = win.getPosition()
106    prevxy.x = x
107    prevxy.y = y */
108    win.setFullScreen(true)
109    isFullScreen = true
110    // console.log('prevxy', prevxy)
111  }
112  function exitFullScreen() {
113    // console.log('退出全屏', isFullScreen)
114    if (isFullScreen) {
115      isFullScreen = false
116      restore()
117    }
118  }
119
120  function restore() {
121    setWindowBounds(win, prevxy)
122  }
123  return {
124    setPrevdata,
125    toggleAddSize,
126    setfs(f) {
127      isFullScreen = f
128    },
129    isFullScreen() {
130      return isFullScreen
131    },
132    toFullScreen,
133    exitFullScreen,
134    restore,
135  }
136}
137
138exports.winScreen = winScreen
139
Full Screen

browserHandler.js

Source: browserHandler.js Github

copy
1const { eventHandler } = require('../eventBus');
2let _browser, _target;
3
4const createdSessionListener = (client) => {
5  _browser = client.Browser;
6  _target = client.Target;
7};
8
9eventHandler.on('createdSession', createdSessionListener);
10
11const overridePermissions = async (origin, permissions) => {
12  await _browser.grantPermissions({ origin, permissions });
13
14  let { targetInfos } = await _target.getTargets();
15  const browserContextIds = [...new Set(targetInfos.map((target) => target.browserContextId))];
16  for (let browserContextId of browserContextIds) {
17    await _browser.grantPermissions({ origin, permissions, browserContextId }).catch((error) => {
18      //browsercontexts from targets does not match available contexts
19      //Need to update using Target.getBrowserContexts() once fixed
20      if (error.message.includes('Failed to find browser context for id')) {
21        return;
22      } else {
23        throw error;
24      }
25    });
26  }
27};
28
29const setWindowBounds = async (targetId, height, width) => {
30  const { windowId } = await _browser.getWindowForTarget({ targetId });
31  await _browser.setWindowBounds({
32    bounds: { height, width },
33    windowId,
34  });
35};
36
37const clearPermissionOverrides = async () => {
38  await _browser.resetPermissions();
39};
40
41module.exports = { clearPermissionOverrides, overridePermissions, setWindowBounds };
42
Full Screen

index.js

Source: index.js Github

copy
1// imports
2  import path from 'path';
3  import fs from 'fs';
4  import * as Service from './service.js';
5  import * as Common from './lib/common.js';
6  import CONFIG from './config.js';
7
8// constants
9  const PROBE_SCREEN = true;
10  const callId = () => (99999*Math.random()+Date.now()).toString(36);
11  const {sleep, DEBUG, DEBUG2} = Common;
12
13  // simple key value store
14  const KV = {};
15  const HasListeners = new Map();
16
17// main export
18    // note that these calls with UI = App.UI
19    // will run against the default (the first) UI created.
20    // but only when called directly from the service side.
21    // when called from UI side, the calls that have a UI parameter
22    // are called on the UI that makes the call or, if the UI parameter is a string
23    // called on the UI having the name equal to that string.
24    // before the App opens a window or
25    // if the 'default' UI is closed there will be no default UI
26    // and calls made from the service side on functions
27    // requiring a UI parameter and without specifying a UI 
28    // parameter will fail at that time
29    // until a new UI (window) is opened (via API.ui.open())
30  const API = {
31    go,                   // start app launch sequence
32    stop,                 // kill app, cleanup, and exit (after async jobs parameter completes)
33    say,                  // say something to console (throws if console closed)
34
35    ui : {
36      open,               // open UI window
37      close,              // close UI window
38      move,               // move UI window (throws if no window open)
39      size,               // size UI window (throws if no window open)
40      minimize,           // minimize UI window (throws if no window open)
41      maximize,           // maximize UI window (throws if no window open)
42      restore,            // switch between maximize and how it was before
43      fullscreen,         // UI window to fullscreen
44      partscreen,         // UI window to part of screen
45      getLayout,          // get window left, right, width, height and windowState
46
47      openBlank,          // open a UI window to about:blank
48      writePage,          // like document.write if using a custom window control box, writes to the
49                          // iframe document inside that
50
51      getScreen,          // get screen dimensions
52    },
53
54    meta: {
55      getStartURL,        // gets the start URL for the app 
56      getFavicon,         // gets a (or an optionally named) favicon as a data URL
57      getTitle,           // gets the app title
58    },
59
60    control: {
61      send,               // send a DevTools command (throws if ui not connected yet)
62      on,                 // start listening for a DevTools event (throws if ui not connected yet)
63      off,                // stop listening for a DevTools event (throws if ui not connected yet)
64    },
65
66    util: {
67      sleep,
68      kv: save,                     // save a (key, value) pair
69      k: load,                      // getrieve a key
70      d: del,
71      hasKey                        // returns a promise that resolves when a key is set
72    },
73
74    _serviceOnly: {
75      publishAPI,         // publish an API into the UI context (requires apiInUI: true)
76      getUI,
77      getApp
78    }
79  };
80
81export default API;
82
83// state variables
84  let App;
85
86// basic functions
87  async function go({
88    uiName:
89      uiName = undefined,             // name for first window opened (if any) 
90    apiInUI:                              // enable grader API available in UI context
91      apiInUI = false,
92    addHandlers:
93      addHandlers = undefined,            // callback to add the route handlers to an express app
94    server:
95      server = null,                      // used to replace the default server
96        // if you don't want a server or if you need 
97        // more control (such as websockets, or TLS)
98        // we call listen automatically
99    keepConsoleOpen:
100      keepConsoleOpen = false,            // keeps the console open in case you need it
101    doLayout:                               
102      doLayout = true,                   // control window layout on screen
103        // true for auto centered mode (default) or
104        // a function with signature: ({screenWidth, screenHeight}) => 
105        // {screenWidth, screenHeight, x, y, width, height}
106        // to set the x,y,width,height base on screenWidth and screenHeight
107    keepAlive: 
108      keepAlive = false,                  // keeps the service running after all windows closed
109        // until it is explicitly killed with stop
110    noWindow:
111      noWindow = false,                   // starts the service but doesn't open a window
112  } = {}) {
113    App = await Service.go({
114      uiName, 
115      apiInUI, addHandlers, 
116      server, keepConsoleOpen, doLayout, keepAlive, noWindow
117    });
118
119    return App;
120  }
121
122  async function stop() {
123    if ( !App ) {
124      throw new TypeError(
125        `API.stop can only be called if App has started and is not already stopped.`
126      );
127    }
128
129    await App.killService();
130  }
131
132  async function say(msg) {
133    try {
134      await App.notify(msg);
135    } catch(e) {
136      DEBUG && console.info("say.App.notify", e);
137      throw new TypeError(
138        `Cannot API.say a console message because App Console has already closed.`
139      );
140    }
141  }
142
143// window functions
144  async function open(settings) {
145    if ( ! App ) throw new TypeError(`Need to call API.go first to create App before opening additional windows.`);
146
147    const {uis,ServicePort} = App;
148    const {uiName: name, keepService, uriPath} = settings;
149    const sessionId = Common.newSessionId();
150    // do layout prep if requrested
151      let layout;
152      if ( settings.doLayout ) {
153        let screenWidth, screenHeight;
154        if ( PROBE_SCREEN ) {
155          ({screenWidth, screenHeight} = await getScreen({
156            ServicePort, 
157            /*
158            sessionId,
159            */
160            uis
161          }));
162        } else {
163          screenWidth = 800;
164          screenHeight = 600;
165        }
166
167        layout = {screenWidth, screenHeight};
168
169        if ( typeof settings.doLayout === "function" ) {
170          layout = settings.doLayout(layout);
171        }
172      }
173
174    fs.writeFileSync('grader.open.log', JSON.stringify({ServicePort, sessionId}));
175    let browser, UI;
176    try {
177      ({UI,browser} = await Service.newBrowser({
178        uis,
179        ServicePort, sessionId, layout, name,
180        keepService,
181        uriPath
182      }));
183      // if not UI yet, this is the first so set it as default
184      if ( ! App.UI ) {
185        App.UI = UI;
186      }
187    } catch(e) {
188      console.log("open.newBrowser", e);
189      fs.writeFileSync('grader.error', JSON.stringify({err:e, msg:e+''}));
190    }
191
192    // don't expose socket
193    UI.socket = null;
194
195    return {UI,browser};
196  }
197
198  async function close(UI = App.UI) {
199    const call = callId();
200    const {browserSessionId,id} = UI;
201    DEBUG2 && console.info({browserSessionId,id,call,close:1});
202    const errors = [];
203
204    if ( ! UI.disconnected ) {
205      try {
206        DEBUG2 && console.info({browserSessionId,id,call,close:2});
207        await UI.send("Browser.close", {}); 
208        DEBUG2 && console.info({browserSessionId,id,call,close:3});
209      } catch(e) {
210        DEBUG2 && console.info('Error closing browser', e);
211        errors.push({msg:'error closing browser', e});
212      }
213
214      try {
215        DEBUG2 && console.info({browserSessionId,id,call,close:4});
216        UI.disconnect();
217        DEBUG2 && console.info({browserSessionId,id,call,close:5});
218      } catch(e) {
219        DEBUG2 && console.info(`Error disconnecting socket`, e);
220        errors.push({msg:'error disconnecting socket', e});
221      }
222    } 
223
224    // does not work
225    //await sleep(1000);
226
227    try {
228      await UI.browser.kill();
229    } catch(e) {
230      DEBUG2 && console.info(`Error kill browser`, e);
231      errors.push({msg:'error kill browser', e});
232    }
233
234    try {
235      DEBUG2 && console.info({browserSessionId,id,call,close:6});
236      UI.cleanSessionDirs();
237      DEBUG2 && console.info({browserSessionId,id,call,close:7});
238    } catch(e) {
239      DEBUG2 && console.info(`Error shut down browser.`, e);
240      errors.push({msg:'error UI.cleanSessionDirs', e});
241    }
242
243    DEBUG2 && console.info({browserSessionId,id,call,close:8});
244    if ( errors.length ) {
245      DEBUG2 && console.log(`API.ui.close`, errors);
246      return {status:'fail', errors};
247    } else {
248      DEBUG2 && console.log(`API.ui.close`, 'success');
249      return {status:'success'};
250    }
251  }
252
253  async function move({x,y}, UI = App.UI) {
254    UI.x = x;
255    UI.y = y;
256    return await UI.send("Browser.setWindowBounds", {
257      windowId: UI.windowId,
258      bounds: {
259        left: x,
260        top: y
261      }
262    });
263  }
264
265  async function size({width,height}, UI = App.UI) {
266    /*
267    await UI.send("Emulation.setDeviceMetricsOverride", {
268      mobile: false,
269      width,
270      height,
271      deviceScaleFactor: 1,
272      screenOrientation: {
273        angle: 0,
274        type: 'portraitPrimary'
275      },
276    });
277    */
278    await UI.send("Browser.setWindowBounds", {
279      windowId: UI.windowId,
280      bounds: {
281        windowState: 'normal',
282        width:0,
283        height:0
284      }
285    });
286    const result = await UI.send("Browser.setWindowBounds", {
287      windowId: UI.windowId,
288      bounds: {
289        windowState: 'normal',
290        width,
291        height
292      }
293    });
294    UI.width = width;
295    UI.height = height;
296    return result;
297  }
298
299  async function minimize(UI = App.UI) {
300    const {windowState} = await getLayout();
301    if ( windowState == 'minimized' ) return;
302    const result = await UI.send("Browser.setWindowBounds", {
303      windowId: UI.windowId,
304      bounds: {
305        windowState: 'minimized'
306      }
307    });
308    return result;
309  }
310
311  async function restore(UI = App.UI) {
312    const {windowState} = await getLayout();
313
314    let result;
315
316    if ( windowState == 'maximized' ) {
317      result = await UI.send("Browser.setWindowBounds", {
318        windowId: UI.windowId,
319        bounds: {
320          windowState: 'normal'
321        }
322      });
323    } else {
324      result = await UI.send("Browser.setWindowBounds", {
325        windowId: UI.windowId,
326        bounds: {
327          windowState: 'maximized'
328        }
329      });
330    }
331    return result;
332  }
333
334  async function maximize(UI = App.UI) {
335    const {windowState} = await getLayout();
336
337    if ( windowState == 'minimized' ) {
338      await partscreen(UI);
339    }
340    const result = await UI.send("Browser.setWindowBounds", {
341      windowId: UI.windowId,
342      bounds: {
343        windowState: 'maximized'
344      }
345    });
346    return result;
347  }
348
349  async function fullscreen(UI = App.UI) {
350    const {windowState} = await getLayout();
351
352    if ( windowState == 'minimized' ) {
353      await partscreen(UI);
354    }
355
356    const result = await UI.send("Browser.setWindowBounds", {
357      windowId: UI.windowId,
358      bounds: {
359        windowState: 'fullscreen'
360      }
361    });
362
363    return result;
364  }
365
366  async function partscreen(UI = App.UI) {
367    const {windowState} = await getLayout();
368
369    if ( windowState == 'normal' ) return;
370
371    const result = await UI.send("Browser.setWindowBounds", {
372      windowId: UI.windowId,
373      bounds: {
374        windowState: 'normal'
375      }
376    });
377
378    return result;
379  }
380
381  async function getLayout(UI = App.UI) {
382    const {bounds} = await UI.send("Browser.getWindowBounds", {
383      windowId: UI.windowId
384    });
385    return bounds;
386  }
387
388// window functions part ii
389  async function openBlank() {
390    throw new TypeError(`Not implemented yet.`);
391  }
392
393  async function writePage() {
394    throw new TypeError(`Not implemented yet.`);
395  }
396
397// meta functions
398  async function getStartURL(UI = App.UI) {
399    return UI.startUrl;
400  }
401
402  async function getFavicon() {
403    const iconPath = path.resolve(Service.SITE_PATH, '_icons', 'favicon.ico');  
404    const base64Icon = fs.readFileSync(iconPath, {encoding:'base64'});
405    const dataURL = `data:image/ico;base64,${base64Icon}`;
406    return dataURL;
407  }
408
409  async function getTitle() {
410    return CONFIG.name;
411  }
412
413// window functions part iii
414  async function getScreen({ServicePort, sessionId: providedSessionId, uis} = {}) {
415    console.log(`Getting screen`);
416    let screen = load('screen');
417
418    if ( !screen ) {
419      // open a headless browser to a page that sends us the screen details
420        let UI;
421        try {
422          ({UI} = await Service.newBrowser({
423            uis,
424            silent: true,
425            headless: true, 
426            uriPath: '/_api/getscreen.html',
427            ServicePort, 
428            sessionId: providedSessionId || Common.newSessionId(),
429            // we will delete directories unless provided with a sessionId
430              // which can save time for main UI startup as the headless
431              // window prepares all the session directories
432            noDelete: providedSessionId ? true : false,
433            // we don't want to kill the whole service when we close this UI
434            // and we have no other UIs open
435            // since often this UI comes before others to provide the screen details
436            // for layout
437            keepService: true
438          }));
439        } catch(e) {
440          console.log("getScreen.newBrowser", e);
441          fs.writeFileSync('grader.error', JSON.stringify({err:e, msg:e+''}));
442        }
443      
444      // wait until the key is set
445        await hasKey('screen');
446
447      // kill the browser __ it has served its purpose, honorably and nobly
448        await close(UI); 
449      
450      screen = load('screen');
451    }
452
453    console.log({screen});
454
455    return screen;
456  }
457
458// control functions
459  async function send(command, params, UI = App.UI) {
460    return await UI.send(command, params);
461  }
462
463  async function on(eventName, handler, UI = App.UI) {
464    return await UI.on(eventName, handler);
465  }
466
467  function off() {
468    throw new TypeError(`off is not implemented yet...`);
469  }
470
471// util part i: KV functions (keys are strings)
472  function save(key, value) {
473    DEBUG && console.log({save:{key,value}});
474    key += '';
475    if ( typeof value == "object" ) {
476      // do a pseudo merge
477      let newValue;
478      if ( Array.isArray(value) ) {
479        const existing = KV[key] || [];
480        if ( Array.isArray(existing) ) {
481          newValue = [...existing, ...value];
482        } else if ( typeof existing == "object" ) {
483          value.forEach((v,i) => {
484            existing[i] = v;
485          });
486          newValue = existing;
487        } else {
488          newValue = value;
489        }
490      } else {
491        const existing = KV[key] || {};
492        newValue = Object.assign(existing, value);
493      }
494      KV[key] = newValue;
495    } else {
496      KV[key] = value;
497    }
498
499    // run any listeners waiting for this key to be set
500      let listeners = HasListeners.get(key);
501      if ( listeners ) {
502        HasListeners.delete(key);
503        listeners.forEach(res => {
504          // execute each without a stack
505          setTimeout(() => res(true), 0);
506        });
507      }
508  }
509
510  function load(key) {
511    key += '';
512    return KV[key];
513  }
514
515  function del(key) {
516    key += '';
517    delete KV[key];
518  }
519
520  // returns a promise that resolves to true when the key is set
521    async function hasKey(key) {
522      key += '';
523
524      let resolve;
525      const pr = new Promise(res => resolve = res);
526
527      let hasKey = false;
528
529      hasKey = Object.prototype.hasOwnProperty.call(KV, key);
530
531      if ( hasKey ) {
532        return resolve(true);
533      } else {
534        let listeners = HasListeners.get(key);
535        if ( ! listeners ) {
536          listeners = [];
537          HasListeners.set(key, listeners);
538        }
539        // these listeners will be called by save once key is set
540        listeners.push(resolve);
541      }
542
543      return pr;
544    }
545
546// service only functions (not available over the API bridge to UI)
547  function publishAPI(apiRoot, slotName) {
548    // apiRoot is an object with properties that enumerate all the functions of that API
549    // e.g. if your API is "sendEmail", "checkReplies", your apiRoot is
550    // {sendEmail, checkReplies}
551    // you can overwrite built-in APIs (like uitl, ui, control and window)
552    // but we throw if you try to overwrite those APIs you publish
553    Object.defineProperty(API, slotName, {
554      get: () => apiRoot,
555      set() {
556        throw new TypeError(`API slot ${slotName} is already present and cannot be overwritten.`);
557      }
558    });
559  }
560
561  function getUI(name) {
562    if ( ! App ) {
563      throw new TypeError(`Cannot call getUI when App does not exist.`);
564    }
565    if ( App.uis.has(name) ) {
566      return App.uis.get(name);
567    } else {
568      throw new TypeError(`UI with name ${name} does not exist.`);
569    }
570  }
571
572  function getApp() {
573    if ( ! App ) {
574      throw new TypeError(`Cannot call getApp when App does not exist.`);
575    }
576    return App;
577  }
578  
579
Full Screen

Accelerate Your Automation Test Cycles With LambdaTest

Leverage LambdaTest’s cloud-based platform to execute your automation tests in parallel and trim down your test execution time significantly. Your first 100 automation testing minutes are on us.

Try LambdaTest

Run JavaScript Tests on LambdaTest Cloud Grid

Execute automation tests with Playwright Internal on a cloud-based Grid of 3000+ real browsers and operating systems for both web and mobile applications.

Test now for Free
LambdaTestX

We use cookies to give you the best experience. Cookies help to provide a more personalized experience and relevant advertising for you, and web analytics for us. Learn More in our Cookies policy, Privacy & Terms of service

Allow Cookie
Sarah

I hope you find the best code examples for your project.

If you want to accelerate automated browser testing, try LambdaTest. Your first 100 automation testing minutes are FREE.

Sarah Elson (Product & Growth Lead)