diff --git a/installer/mac/postinstall.sh b/installer/mac/postinstall.sh index 08beeefc..5c71487f 100755 --- a/installer/mac/postinstall.sh +++ b/installer/mac/postinstall.sh @@ -46,9 +46,5 @@ rm -f $tempFilePath ## For launching symphony with sandbox enabled, create a shell script that is used as the launch point for the app EXEC_PATH=$installPath/Symphony.app/Contents/MacOS -mv $EXEC_PATH/Symphony $EXEC_PATH/Symphony-bin -cat > $EXEC_PATH/Symphony << EOT -#!/bin/sh -exec "\${0%/*}/Symphony-bin" --enable-sandbox \$@ -EOT -chmod 755 $EXEC_PATH/Symphony \ No newline at end of file +exec $EXEC_PATH/Symphony --install $newPath +chmod 755 $EXEC_PATH/Symphony diff --git a/installer/win/Symphony-x64.aip b/installer/win/Symphony-x64.aip index 7d71dd17..49beae9a 100644 --- a/installer/win/Symphony-x64.aip +++ b/installer/win/Symphony-x64.aip @@ -57,7 +57,6 @@ - @@ -69,16 +68,15 @@ - + - + - - + @@ -362,7 +360,7 @@ - + diff --git a/js/main.js b/js/main.js index 0d74cd86..0e96522f 100644 --- a/js/main.js +++ b/js/main.js @@ -9,7 +9,11 @@ const urlParser = require('url'); const { getConfigField } = require('./config.js'); const { isMac, isDevEnv } = require('./utils/misc.js'); const protocolHandler = require('./protocolHandler'); -const getCmdLineArg = require('./utils/getCmdLineArg.js') +const getCmdLineArg = require('./utils/getCmdLineArg.js'); +const childProcess = require('child_process'); +const path = require('path'); +const AppDirectory = require('appdirectory'); +const dirs = new AppDirectory('Symphony'); require('electron-dl')(); @@ -94,9 +98,18 @@ function setupThenOpenMainWindow() { let hasInstallFlag = getCmdLineArg(process.argv, '--install', true); if (!isMac && hasInstallFlag) { getConfigField('launchOnStartup') - .then(setStartup) - .then(app.quit) - .catch(app.quit); + .then(setStartup) + .then(updateUserConfigWin) + .then(app.quit) + .catch(app.quit); + return; + } + + // allows mac installer to overwrite user config + if (isMac && hasInstallFlag) { + updateUserConfigMac() + .then(app.quit) + .catch(app.quit); return; } @@ -118,6 +131,37 @@ function setStartup(lStartup){ }); } +// Method to overwrite user config on mac installer +function updateUserConfigMac() { + return new Promise((resolve, reject) => { + let userConfigPath = dirs.userConfig() + '/'; + let globalConfigPath = process.argv[2]; + let userName = process.env.USER; + + childProcess.exec(`rsync -r "${globalConfigPath}" "${userConfigPath}" && chown -R "${userName}" "${userConfigPath}"`, {timeout: 60000}, (err) => { + if (err) { + reject(err); + } + resolve(); + }); + }); +} + +// Method to overwrite user config on windows installer +function updateUserConfigWin() { + return new Promise((resolve, reject) => { + let userConfigPath = app.getPath('userData'); + let globalConfigPath = path.join(__dirname, '..', '..', '..', 'config/Symphony.config'); + + childProcess.exec(`echo D|xcopy /y /e /s /c "${globalConfigPath}" "${userConfigPath}"`, {timeout: 60000}, (err) => { + if (err) { + reject(err); + } + resolve(); + }); + }); +} + function getUrlAndCreateMainWindow() { // for dev env allow passing url argument if (isDevEnv) { diff --git a/js/notify/electron-notify.js b/js/notify/electron-notify.js index bf053d41..98d793aa 100644 --- a/js/notify/electron-notify.js +++ b/js/notify/electron-notify.js @@ -48,6 +48,8 @@ let externalDisplay; // user selected display id for notification let displayId; +let sandboxed = false; + let config = { // corner to put notifications // upper-right, upper-left, lower-right, lower-left @@ -131,7 +133,7 @@ let config = { acceptFirstMouse: true, webPreferences: { preload: path.join(__dirname, 'electron-notify-preload.js'), - sandbox: !isNodeEnv, + sandbox: sandboxed, nodeIntegration: isNodeEnv } } diff --git a/js/notify/settings/configure-notification-position.js b/js/notify/settings/configure-notification-position.js index 070a156d..52c72ffe 100644 --- a/js/notify/settings/configure-notification-position.js +++ b/js/notify/settings/configure-notification-position.js @@ -17,6 +17,7 @@ let configurationWindow; let screens; let position; let display; +let sandboxed = false; let windowConfig = { width: 460, @@ -27,7 +28,7 @@ let windowConfig = { resizable: false, webPreferences: { preload: path.join(__dirname, 'configure-notification-position-preload.js'), - sandbox: true, + sandbox: sandboxed, nodeIntegration: false } }; diff --git a/js/windowMgr.js b/js/windowMgr.js index def70ddb..056e3e92 100644 --- a/js/windowMgr.js +++ b/js/windowMgr.js @@ -37,6 +37,7 @@ let boundsChangeWindow; let alwaysOnTop = false; let position = 'lower-right'; let display; +let sandboxed = false; // note: this file is built using browserify in prebuild step. const preloadMainScript = path.join(__dirname, 'preload/_preloadMain.js'); @@ -81,9 +82,10 @@ function doCreateMainWindow(initialUrl, initialBounds) { minHeight: MIN_HEIGHT, alwaysOnTop: false, webPreferences: { - sandbox: !isNodeEnv, + sandbox: sandboxed, nodeIntegration: isNodeEnv, preload: preloadMainScript, + nativeWindowOpen: true } }; @@ -212,6 +214,9 @@ function doCreateMainWindow(initialUrl, initialBounds) { // bug in electron is preventing this from working in sandboxed evt... // https://github.com/electron/electron/issues/8841 mainWindow.webContents.on('will-navigate', function(event, willNavUrl) { + if (!sandboxed) { + return; + } event.preventDefault(); openUrlInDefaultBrower(willNavUrl); }); diff --git a/package.json b/package.json index 27887016..8385912c 100644 --- a/package.json +++ b/package.json @@ -12,12 +12,14 @@ "demo-win-search": "npm run prebuild && cross-env ELECTRON_DEV=true electron . --url=file:///demo/search.html", "demo-mac-search": "npm run prebuild && cross-env ELECTRON_DEV=true electron . --url=file://$(pwd)/demo/search.html", "unpacked-mac": "npm run prebuild && npm run test && build --mac --dir", - "unpacked-win": "npm run prebuild && npm run test && build --win --x64 --dir && npm run rename-exe", - "unpacked-win-x86": "npm run prebuild && npm run test && build --win --ia32 --dir && npm run rename-exe", + "packed-mac": "npm run unpacked-mac && packagesbuild -v installer/mac/symphony-mac-packager.pkgproj", + "unpacked-win": "npm run prebuild && npm run test && build --win --x64 --dir", + "unpacked-win-x86": "npm run prebuild && npm run test && build --win --ia32", "prebuild": "npm run rebuild && npm run browserify-preload", "browserify-preload": "browserify -o js/preload/_preloadMain.js -x electron --insert-global-vars=__filename,__dirname js/preload/preloadMain.js", "rebuild": "electron-rebuild -f", - "test": "npm run lint && jest --verbose --testPathPattern test --runInBand", + "test": "npm run lint && jest --verbose --testPathPattern test && npm run rebuild", + "spectron-test": "jest --config tests/spectron/jest_spectron.json --runInBand && npm run rebuild", "lint": "eslint --ext .js js/", "rename-exe": "cd dist/win-unpacked && ren Symphony.exe Symphony-Electron.exe" }, @@ -70,7 +72,7 @@ "devDependencies": { "browserify": "^14.1.0", "cross-env": "^3.2.4", - "electron": "1.6.11", + "electron": "1.7.5", "electron-builder": "^13.9.0", "electron-builder-squirrel-windows": "^12.3.0", "electron-packager": "^8.5.2", @@ -90,10 +92,11 @@ "async": "^2.1.5", "auto-launch": "^5.0.1", "electron-context-menu": "^0.8.0", - "electron-dl": "^1.9.0", "electron-squirrel-startup": "^1.0.0", - "filesize": "^3.5.10", "keymirror": "0.1.1", + "electron-dl": "^1.9.0", + "filesize": "^3.5.10", + "appdirectory": "^0.1.0", "randomstring": "^1.1.5", "winreg": "^1.2.3" }, diff --git a/tests/activityDetection.test.js b/tests/activityDetection.test.js index f9f77263..09d042c0 100644 --- a/tests/activityDetection.test.js +++ b/tests/activityDetection.test.js @@ -3,10 +3,10 @@ const childProcess = require('child_process'); let activityDetection; -describe('Tests for Activity Detection', function() { +describe('Tests for Activity Detection', function () { var originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL; - jasmine.DEFAULT_TIMEOUT_INTERVAL = 60000; + jasmine.DEFAULT_TIMEOUT_INTERVAL = 90000; beforeAll(function (done) { childProcess.exec(`npm rebuild --target=${process.version} --build-from-source`, function (err) { @@ -21,13 +21,11 @@ describe('Tests for Activity Detection', function() { }); afterAll(function (done) { - childProcess.exec('npm run rebuild', function (err, stdout) { - jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout; - done(); - }); + jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout; + done(); }); - it('should return null', function() { + it('should return null', function () { activityDetection.setActivityWindow(0, electron.ipcRenderer); const noData = activityDetection.activityDetection(); diff --git a/tests/alwaysOnTop.test.js b/tests/spectron/alwaysOnTop.spectron.js similarity index 91% rename from tests/alwaysOnTop.test.js rename to tests/spectron/alwaysOnTop.spectron.js index f843529f..d007fd56 100644 --- a/tests/alwaysOnTop.test.js +++ b/tests/spectron/alwaysOnTop.spectron.js @@ -1,5 +1,5 @@ -const Application = require('./spectron/spectronSetup'); -const {isMac} = require('../js/utils/misc.js'); +const Application = require('./spectronSetup'); +const {isMac} = require('../../js/utils/misc.js'); const childProcess = require('child_process'); let app = new Application({}); @@ -46,16 +46,12 @@ describe('Tests for Always on top', () => { if (app && app.isRunning()) { jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout; app.stop().then(() => { - childProcess.exec('npm run rebuild', function (err, stdout) { - jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout; - done(); - }); + jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout; + done(); }).catch((err) => { - childProcess.exec('npm run rebuild', function () { - jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout; - expect(err).toBeNull(); - done(); - }); + jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout; + expect(err).toBeNull(); + done(); }); } }); diff --git a/tests/bringToFront.test.js b/tests/spectron/bringToFront.spectron.js similarity index 97% rename from tests/bringToFront.test.js rename to tests/spectron/bringToFront.spectron.js index f9eee252..dbd2363b 100644 --- a/tests/bringToFront.test.js +++ b/tests/spectron/bringToFront.spectron.js @@ -1,4 +1,4 @@ -const Application = require('./spectron/spectronSetup'); +const Application = require('./spectronSetup'); let app = new Application({}); describe('Tests for Bring to front', () => { diff --git a/tests/clipboard.test.js b/tests/spectron/clipboard.spectron.js similarity index 96% rename from tests/clipboard.test.js rename to tests/spectron/clipboard.spectron.js index 98200f89..b06bcab6 100644 --- a/tests/clipboard.test.js +++ b/tests/spectron/clipboard.spectron.js @@ -1,4 +1,4 @@ -const Application = require('./spectron/spectronSetup'); +const Application = require('./spectronSetup'); const path = require('path'); let app = new Application({}); @@ -40,7 +40,7 @@ describe('Tests for clipboard', () => { }); it('should check window count', () => { - return app.client.url('file:///' + path.join(__dirname, '..', 'demo/index.html')); + return app.client.url('file:///' + path.join(__dirname, '..', '..', 'demo/index.html')); }); it('should set the username field', () => { diff --git a/tests/spectron/close.spectron.js b/tests/spectron/close.spectron.js new file mode 100644 index 00000000..6417b28b --- /dev/null +++ b/tests/spectron/close.spectron.js @@ -0,0 +1,70 @@ +describe('Tests for Close', () => { + + let originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL; + jasmine.DEFAULT_TIMEOUT_INTERVAL = 90000; + + let app; + + beforeAll((done) => { + const Application = require('./spectronSetup'); + app = new Application({}); + return app.startApplication().then((startedApp) => { + app = startedApp; + done(); + }).catch((err) => { + expect(err).toBeNull(); + }); + }); + + afterAll((done) => { + if (app && app.isRunning()) { + jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout; + app.stop().then(() => { + done(); + }).catch((err) => { + console.log(err); + done(); + }); + } else { + done(); + } + }); + + it('should launch the app', (done) => { + return app.client.waitUntilWindowLoaded().then(() => { + return app.client.getWindowCount().then((count) => { + expect(count === 1).toBeTruthy(); + done(); + }).catch((err) => { + expect(err).toBeNull(); + }); + }).catch((err) => { + expect(err).toBeNull(); + }); + }); + + it('should check window count', () => { + return app.client.getWindowCount().then((count) => { + expect(count === 1).toBeTruthy(); + }).catch((err) => { + expect(err).toBeNull(); + }); + }); + + it('should check browser window visibility', () => { + return app.browserWindow.isVisible().then((isVisible) => { + expect(isVisible).toBeTruthy(); + }).catch((err) => { + expect(err).toBeNull(); + }); + }); + + it('should close the app', () => { + return app.stop(); + }); + + it('should check whether the app is running', () => { + expect(app.isRunning()).toBe(false); + }); + +}); \ No newline at end of file diff --git a/tests/spectron/full-screen.spectron.js b/tests/spectron/full-screen.spectron.js new file mode 100644 index 00000000..1e71ca56 --- /dev/null +++ b/tests/spectron/full-screen.spectron.js @@ -0,0 +1,142 @@ +const path = require('path'); +const fs = require('fs'); +const childProcess = require('child_process'); +const Application = require('./spectronSetup'); +const {isMac} = require('../../js/utils/misc'); +let robot; +let configPath; + +let app = new Application({}); + +describe('Tests for Full screen', () => { + + let originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL; + jasmine.DEFAULT_TIMEOUT_INTERVAL = 90000; + + beforeAll((done) => { + childProcess.exec(`npm rebuild robotjs --target=${process.version} --build-from-source`, function () { + robot = require('robotjs'); + return app.startApplication().then((startedApp) => { + app = startedApp; + getConfigPath().then((config) => { + console.log(config); + configPath = config; + done(); + }).catch((err) => { + expect(err).toBeNull(); + }); + }).catch((err) => { + expect(err).toBeNull(); + }); + }); + }); + + function getConfigPath() { + return new Promise(function (resolve, reject) { + app.client.addCommand('getUserDataPath', function () { + return this.execute(function () { + return require('electron').remote.app.getPath('userData'); + }) + }); + app.client.getUserDataPath().then((path) => { + resolve(path.value + '/Symphony.config') + }).catch((err) => { + reject(err); + }); + }); + } + + afterAll((done) => { + if (app && app.isRunning()) { + jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout; + app.client.getWindowCount().then((count) => { + if (count > 0) { + app.stop().then(() => { + done(); + }).catch((err) => { + console.log(err); + done(); + }); + } else { + done(); + } + }) + } else { + done(); + } + }); + + it('should launch the app', (done) => { + return app.client.waitUntilWindowLoaded().then(() => { + return app.client.getWindowCount().then((count) => { + expect(count === 1).toBeTruthy(); + done(); + }).catch((err) => { + expect(err).toBeNull(); + }); + }).catch((err) => { + expect(err).toBeNull(); + }); + }); + + it('should check window count', () => { + return app.client.getWindowCount().then((count) => { + expect(count === 1).toBeTruthy(); + }).catch((err) => { + expect(err).toBeNull(); + }); + }); + + it('should check browser window visibility', () => { + return app.browserWindow.isVisible().then((isVisible) => { + expect(isVisible).toBeTruthy(); + }).catch((err) => { + expect(err).toBeNull(); + }); + }); + + it('should bring the app to top', () => { + app.browserWindow.focus(); + return app.browserWindow.setAlwaysOnTop(true).then(() => { + return app.browserWindow.isAlwaysOnTop().then((isOnTop) => { + console.log(isOnTop); + expect(isOnTop).toBeTruthy(); + }); + }); + }); + + it('should set the app full screen and check whether it is in full screen', () => { + if (isMac) { + robot.setMouseDelay(100); + robot.moveMouseSmooth(205, 10); + robot.mouseClick(); + robot.setKeyboardDelay(100); + for (let i = 0; i < 6; i++) { + robot.keyTap('down'); + } + robot.keyTap('enter'); + + return app.browserWindow.isFullScreen().then((fullscreen) => { + expect(fullscreen).toBeTruthy(); + }).catch((err) => { + expect(err).toBeNull(); + }) + } else { + return app.browserWindow.getBounds().then((bounds) => { + robot.setMouseDelay(100); + let x = bounds.x + 200; + let y = bounds.y + 200; + robot.moveMouseSmooth(x, y); + robot.mouseClick(); + + robot.keyTap('f11'); + + return app.browserWindow.isFullScreen().then((fullscreen) => { + expect(fullscreen).toBeTruthy(); + }).catch((err) => { + expect(err).toBeNull(); + }) + }); + } + }); +}); \ No newline at end of file diff --git a/tests/spectron/jest_spectron.json b/tests/spectron/jest_spectron.json new file mode 100644 index 00000000..abd4d921 --- /dev/null +++ b/tests/spectron/jest_spectron.json @@ -0,0 +1,4 @@ +{ + "testMatch": ["**/*.spectron.js"], + "verbose": true +} diff --git a/tests/spectron/minimize-on-close.spectron.js b/tests/spectron/minimize-on-close.spectron.js new file mode 100644 index 00000000..f07d3f5f --- /dev/null +++ b/tests/spectron/minimize-on-close.spectron.js @@ -0,0 +1,196 @@ +const path = require('path'); +const fs = require('fs'); +const childProcess = require('child_process'); +const Application = require('./spectronSetup'); +const {isMac} = require('../../js/utils/misc'); +let robot; +let configPath; + +let app = new Application({}); + +describe('Tests for Minimize on Close', () => { + + let originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL; + jasmine.DEFAULT_TIMEOUT_INTERVAL = 90000; + + beforeAll((done) => { + childProcess.exec(`npm rebuild robotjs --target=${process.version} --build-from-source`, function () { + robot = require('robotjs'); + return app.startApplication().then((startedApp) => { + app = startedApp; + getConfigPath().then((config) => { + console.log(config); + configPath = config; + done(); + }).catch((err) => { + expect(err).toBeNull(); + }); + }).catch((err) => { + expect(err).toBeNull(); + }); + }); + }); + + function getConfigPath() { + return new Promise(function (resolve, reject) { + app.client.addCommand('getUserDataPath', function () { + return this.execute(function () { + return require('electron').remote.app.getPath('userData'); + }) + }); + app.client.getUserDataPath().then((path) => { + resolve(path.value + '/Symphony.config') + }).catch((err) => { + reject(err); + }); + }); + } + + afterAll((done) => { + if (app && app.isRunning()) { + jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout; + app.client.getWindowCount().then((count) => { + if (count > 0) { + app.stop().then(() => { + done(); + }).catch((err) => { + console.log(err); + done(); + }); + } else { + done(); + } + }) + } else { + done(); + } + }); + + it('should launch the app', (done) => { + return app.client.waitUntilWindowLoaded().then(() => { + return app.client.getWindowCount().then((count) => { + expect(count === 1).toBeTruthy(); + done(); + }).catch((err) => { + expect(err).toBeNull(); + }); + }).catch((err) => { + expect(err).toBeNull(); + }); + }); + + it('should check window count', () => { + return app.client.getWindowCount().then((count) => { + expect(count === 1).toBeTruthy(); + }).catch((err) => { + expect(err).toBeNull(); + }); + }); + + it('should check browser window visibility', () => { + return app.browserWindow.isVisible().then((isVisible) => { + expect(isVisible).toBeTruthy(); + }).catch((err) => { + expect(err).toBeNull(); + }); + }); + + it('should bring the app to top', () => { + app.browserWindow.focus(); + return app.browserWindow.setAlwaysOnTop(true).then(() => { + return app.browserWindow.isAlwaysOnTop().then((isOnTop) => { + console.log(isOnTop); + expect(isOnTop).toBeTruthy(); + }); + }); + }); + + it('should check whether the app is minimized', (done) => { + Application.readConfig(configPath).then((userConfig) => { + if (isMac) { + if (userConfig.minimizeOnClose) { + robot.setKeyboardDelay(100); + robot.keyToggle('w', 'down', ['command']); + robot.keyToggle('w', 'up'); + robot.keyToggle('command', 'up'); + app.browserWindow.isMinimized().then(function (minimized) { + expect(minimized).toBeTruthy(); + done(); + }).catch((err) => { + expect(err).toBeNull(); + done(); + }); + } else { + + robot.setMouseDelay(100); + robot.moveMouseSmooth(200, 10); + robot.mouseClick(); + robot.setKeyboardDelay(100); + + for (let i = 0; i < 9; i++) { + robot.keyTap('down'); + } + robot.keyTap('enter'); + + robot.keyToggle('w', 'down', ['command']); + robot.keyToggle('w', 'up'); + robot.keyToggle('command', 'up'); + app.browserWindow.isMinimized().then(function (minimized) { + expect(minimized).toBeTruthy(); + done(); + }).catch((err) => { + expect(err).toBeNull(); + done(); + }); + } + } else { + if (!userConfig.minimizeOnClose) { + app.browserWindow.getBounds().then((bounds) => { + robot.setMouseDelay(100); + let x = bounds.x + 95; + let y = bounds.y + 35; + robot.moveMouse(x, y); + robot.mouseClick(); + for (let i = 0; i < 5; i++) { + robot.keyTap('down'); + } + robot.keyTap('enter'); + + robot.keyToggle('w', 'down', ['control']); + robot.keyToggle('w', 'up'); + robot.keyToggle('control', 'up'); + app.browserWindow.isMinimized().then(function (minimized) { + expect(minimized).toBeTruthy(); + done(); + }).catch((err) => { + expect(err).toBeNull(); + done(); + }); + }); + } else { + app.browserWindow.getBounds().then((bounds) => { + robot.setMouseDelay(100); + let x = bounds.x + 200; + let y = bounds.y + 200; + robot.moveMouseSmooth(x, y); + robot.mouseClick(); + robot.keyToggle('w', 'down', ['control']); + robot.keyToggle('w', 'up'); + robot.keyToggle('control', 'up'); + app.browserWindow.isMinimized().then(function (minimized) { + expect(minimized).toBeTruthy(); + done(); + }).catch((err) => { + expect(err).toBeNull(); + done(); + }); + }); + } + } + }).catch((err) => { + expect(err).toBeNull(); + done(); + }) + }); + +}); \ No newline at end of file diff --git a/tests/notificationPosition.test.js b/tests/spectron/notificationPosition.spectron.js similarity index 92% rename from tests/notificationPosition.test.js rename to tests/spectron/notificationPosition.spectron.js index b196700d..79cedd20 100644 --- a/tests/notificationPosition.test.js +++ b/tests/spectron/notificationPosition.spectron.js @@ -1,5 +1,6 @@ -const Application = require('./spectron/spectronSetup'); +const Application = require('./spectronSetup'); const path = require('path'); +const {isMac} = require('../../js/utils/misc'); let app = new Application({}); describe('Tests for Notification position', () => { @@ -42,13 +43,7 @@ describe('Tests for Notification position', () => { }); it('should load demo html page', () => { - let filePath; - if (process.platform === 'win32') { - filePath = 'file:///' + path.join(__dirname, '..', 'demo/index.html'); - } else { - filePath = 'file://$(pwd)/' + path.join(__dirname, '..', 'demo/index.html') - } - return app.client.url(filePath); + return app.client.url('file:///' + path.join(__dirname, '..', '..', 'demo/index.html')); }); it('should load demo html', () => { @@ -77,7 +72,11 @@ describe('Tests for Notification position', () => { it('should check notification position', () => { return app.browserWindow.getBounds().then((bounds) => { expect(bounds.x === 0).toBeTruthy(); - expect(bounds.y > 0).toBeTruthy(); + if (isMac) { + expect(bounds.y > 0).toBeTruthy(); + } else { + expect(bounds.y === 0).toBeTruthy(); + } }).catch((err) => { expect(err).toBeNull(); }); @@ -157,7 +156,11 @@ describe('Tests for Notification position', () => { it('should check notification position and equal to upper-right', () => { return app.browserWindow.getBounds().then((bounds) => { expect(bounds.x > 0).toBeTruthy(); - expect(bounds.y > 0).toBeTruthy(); + if (isMac) { + expect(bounds.y > 0).toBeTruthy(); + } else { + expect(bounds.y === 0).toBeTruthy(); + } }).catch((err) => { expect(err).toBeNull(); }); diff --git a/tests/spectron/zoom-in-zoom-out.spectron.js b/tests/spectron/zoom-in-zoom-out.spectron.js new file mode 100644 index 00000000..c9840c3b --- /dev/null +++ b/tests/spectron/zoom-in-zoom-out.spectron.js @@ -0,0 +1,200 @@ +const path = require('path'); +const fs = require('fs'); +const childProcess = require('child_process'); +const Application = require('./spectronSetup'); +const {isMac} = require('../../js/utils/misc'); +let robot; +let configPath; + +let app = new Application({}); + +describe('Tests for Zoom in and Zoom out', () => { + + let originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL; + jasmine.DEFAULT_TIMEOUT_INTERVAL = 90000; + + beforeAll((done) => { + childProcess.exec(`npm rebuild robotjs --target=${process.version} --build-from-source`, function () { + robot = require('robotjs'); + return app.startApplication().then((startedApp) => { + app = startedApp; + getConfigPath().then((config) => { + configPath = config; + done(); + }).catch((err) => { + expect(err).toBeNull(); + }); + }).catch((err) => { + expect(err).toBeNull(); + }); + }); + }); + + function getConfigPath() { + return new Promise(function (resolve, reject) { + app.client.addCommand('getUserDataPath', function () { + return this.execute(function () { + return require('electron').remote.app.getPath('userData'); + }) + }); + app.client.getUserDataPath().then((path) => { + resolve(path.value + '/Symphony.config') + }).catch((err) => { + reject(err); + }); + }); + } + + afterAll((done) => { + if (app && app.isRunning()) { + jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout; + app.client.getWindowCount().then((count) => { + if (count > 0) { + app.stop().then(() => { + done(); + }).catch((err) => { + console.log(err); + done(); + }); + } else { + done(); + } + }) + } else { + done(); + } + }); + + it('should launch the app', (done) => { + return app.client.waitUntilWindowLoaded().then(() => { + return app.client.getWindowCount().then((count) => { + expect(count === 1).toBeTruthy(); + done(); + }).catch((err) => { + expect(err).toBeNull(); + }); + }).catch((err) => { + expect(err).toBeNull(); + }); + }); + + it('should check window count', () => { + return app.client.getWindowCount().then((count) => { + expect(count === 1).toBeTruthy(); + }).catch((err) => { + expect(err).toBeNull(); + }); + }); + + it('should check browser window visibility', () => { + return app.browserWindow.isVisible().then((isVisible) => { + expect(isVisible).toBeTruthy(); + }).catch((err) => { + expect(err).toBeNull(); + }); + }); + + it('should bring the app to top', () => { + app.browserWindow.focus(); + return app.browserWindow.setAlwaysOnTop(true).then(() => { + return app.browserWindow.isAlwaysOnTop().then((isOnTop) => { + expect(isOnTop).toBeTruthy(); + }); + }); + }); + + it('should zoom in the app and check whether it is zoomed in', () => { + robot.setKeyboardDelay(500); + if (isMac) { + + robot.keyToggle('0', 'down', ['command']); + robot.keyToggle('0', 'up'); + robot.keyToggle('command', 'up'); + + for (var i = 0; i < 4; i++) { + robot.keyToggle('+', 'down', ['command']); + } + robot.keyToggle('+', 'up'); + robot.keyToggle('command', 'up'); + + return app.electron.webFrame.getZoomFactor().then((zoomFactor) => { + expect(zoomFactor > 1).toBeTruthy(); + }).catch((err) => { + expect(err).toBeNull(); + }) + } else { + return app.browserWindow.getBounds().then((bounds) => { + robot.setMouseDelay(100); + let x = bounds.x + 200; + let y = bounds.y + 200; + robot.moveMouseSmooth(x, y); + robot.mouseClick(); + + robot.keyToggle('0', 'down', ['control']); + robot.keyToggle('0', 'up'); + robot.keyToggle('control', 'up'); + + for (var i = 0; i < 4; i++) { + robot.keyToggle('+', 'down', ['control', 'shift']); + } + robot.keyToggle('+', 'up'); + robot.keyToggle('control', 'up'); + robot.keyToggle('shift', 'up'); + + return app.electron.webFrame.getZoomFactor().then((zoomFactor) => { + expect(zoomFactor > 1).toBeTruthy(); + }).catch((err) => { + expect(err).toBeNull(); + }) + }); + } + }); + + + it('should zoom out the app and check whether it is zoomed out', () => { + robot.setKeyboardDelay(500); + if (isMac) { + + robot.keyToggle('0', 'down', ['command']); + robot.keyToggle('0', 'up'); + robot.keyToggle('command', 'up'); + + for (var i = 0; i < 4; i++) { + robot.keyToggle('-', 'down', ['command']); + } + robot.keyToggle('-', 'up'); + robot.keyToggle('command', 'up'); + + return app.electron.webFrame.getZoomFactor().then((zoomFactor) => { + + expect(zoomFactor < 1).toBeTruthy(); + }).catch((err) => { + expect(err).toBeNull(); + }) + } else { + return app.browserWindow.getBounds().then((bounds) => { + robot.setMouseDelay(100); + let x = bounds.x + 200; + let y = bounds.y + 200; + robot.moveMouseSmooth(x, y); + robot.mouseClick(); + + robot.keyToggle('0', 'down', ['control']); + robot.keyToggle('0', 'up'); + robot.keyToggle('control', 'up'); + + for (var i = 0; i < 4; i++) { + robot.keyToggle('-', 'down', ['control']); + } + robot.keyToggle('-', 'up'); + robot.keyToggle('control', 'up'); + + return app.electron.webFrame.getZoomFactor().then((zoomFactor) => { + expect(zoomFactor < 1).toBeTruthy(); + }).catch((err) => { + expect(err).toBeNull(); + }) + }); + } + }); +}); \ No newline at end of file