Browse Source

test: draggable region allows moving window (#41127)

* chore: add nut.js

* test: dragging window updates position

* instantly move mouse position

* limit platforms to run drag tests on

* defer loading nut-js
Sam Maddock 1 year ago
parent
commit
85bebfb180
4 changed files with 776 additions and 6 deletions
  1. 48 1
      spec/api-browser-window-spec.ts
  2. 13 0
      spec/lib/screen-helpers.ts
  3. 1 0
      spec/package.json
  4. 714 5
      spec/yarn.lock

+ 48 - 1
spec/api-browser-window-spec.ts

@@ -11,7 +11,7 @@ import { app, BrowserWindow, BrowserView, dialog, ipcMain, OnBeforeSendHeadersLi
 import { emittedUntil, emittedNTimes } from './lib/events-helpers';
 import { ifit, ifdescribe, defer, listen } from './lib/spec-helpers';
 import { closeWindow, closeAllWindows } from './lib/window-helpers';
-import { areColorsSimilar, captureScreen, HexColors, getPixelColor } from './lib/screen-helpers';
+import { areColorsSimilar, captureScreen, HexColors, getPixelColor, hasCapturableScreen } from './lib/screen-helpers';
 import { once } from 'node:events';
 import { setTimeout } from 'node:timers/promises';
 import { setTimeout as syncSetTimeout } from 'node:timers';
@@ -6599,4 +6599,51 @@ describe('BrowserWindow module', () => {
       expect(areColorsSimilar(centerColor, HexColors.BLUE)).to.be.true();
     });
   });
+
+  describe('draggable regions', () => {
+    afterEach(closeAllWindows);
+
+    ifit(hasCapturableScreen())('should allow the window to be dragged when enabled', async () => {
+      // WOA fails to load libnut so we're using require to defer loading only
+      // on supported platforms.
+      // "@nut-tree\libnut-win32\build\Release\libnut.node is not a valid Win32 application."
+      const { mouse, straightTo, centerOf, Region, Button } = require('@nut-tree/nut-js') as typeof import('@nut-tree/nut-js');
+
+      const display = screen.getPrimaryDisplay();
+
+      const w = new BrowserWindow({
+        x: 0,
+        y: 0,
+        width: display.bounds.width / 2,
+        height: display.bounds.height / 2,
+        frame: false,
+        titleBarStyle: 'hidden'
+      });
+
+      const overlayHTML = path.join(__dirname, 'fixtures', 'pages', 'overlay.html');
+      w.loadFile(overlayHTML);
+      await once(w, 'ready-to-show');
+
+      const winBounds = w.getBounds();
+      const titleBarHeight = 30;
+      const titleBarRegion = new Region(winBounds.x, winBounds.y, winBounds.width, titleBarHeight);
+      const screenRegion = new Region(display.bounds.x, display.bounds.y, display.bounds.width, display.bounds.height);
+
+      const startPos = w.getPosition();
+
+      await mouse.setPosition(await centerOf(titleBarRegion));
+      await mouse.pressButton(Button.LEFT);
+      await mouse.drag(straightTo(centerOf(screenRegion)));
+
+      // Wait for move to complete
+      await Promise.race([
+        once(w, 'move'),
+        setTimeout(100) // fallback for possible race condition
+      ]);
+
+      const endPos = w.getPosition();
+
+      expect(startPos).to.not.deep.equal(endPos);
+    });
+  });
 });

+ 13 - 0
spec/lib/screen-helpers.ts

@@ -91,3 +91,16 @@ export const areColorsSimilar = (
   const distance = colorDistance(hexColorA, hexColorB);
   return distance <= distanceThreshold;
 };
+
+/**
+ * Whether the current VM has a valid screen which can be used to capture.
+ *
+ * This is specific to Electron's CI test runners.
+ * - Linux: virtual screen display is 0x0
+ * - Win32 arm64 (WOA): virtual screen display is 0x0
+ * - Win32 ia32: skipped
+ */
+export const hasCapturableScreen = () => {
+  return process.platform === 'darwin' ||
+    (process.platform === 'win32' && process.arch === 'x64');
+};

+ 1 - 0
spec/package.json

@@ -11,6 +11,7 @@
     "@electron-ci/is-valid-window": "file:./is-valid-window",
     "@electron-ci/uv-dlopen": "file:./fixtures/native-addon/uv-dlopen/",
     "@marshallofsound/mocha-appveyor-reporter": "^0.4.3",
+    "@nut-tree/nut-js": "^3.1.2",
     "@types/sinon": "^9.0.4",
     "@types/ws": "^7.2.0",
     "basic-auth": "^2.0.1",

File diff suppressed because it is too large
+ 714 - 5
spec/yarn.lock


Some files were not shown because too many files changed in this diff