Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

release v2.1.0 #165

Merged
merged 16 commits into from
Apr 20, 2019
Merged
Next Next commit
Config of End-to-End & Search window e2e test code (#164)
* Refactor about constant of path

* Config default setting information

* Edit unit test config and repair unit test code

* Fix title about page html

* E2E configure using spectron with jest

* Attach ipc handler to use e2e test

Spectron doesn't support controll of electron window.
So To use end to end test, Attach ipc handler on test environment.

* Add E2E support module

* Add window manager to control electron window on e2e environment

* Add test manager to use convenience

* Initial e2e code for search window

* E2E test main feature of list on search window

* E2E test feature of menu on search window

* Fix unit-test snapshot code
  • Loading branch information
HyunmoAhn authored Jan 23, 2019
commit ab737a17b606d3986992077f3d10049afb52d52e
1 change: 1 addition & 0 deletions .babelrc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"alias": {
"actions": "./app/actions",
"assets": "./app/assets",
"config": "./app/config.js",
"constants": "./app/constants",
"components": "./app/components",
"main": "./app/main",
Expand Down
2 changes: 2 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
"jsx-a11y/heading-has-content": 0,
"react/jsx-one-expression-per-line": 0,
"lines-between-class-members": 0,
"no-continue": 0,
"no-bitwise": 0
},
"parser": "babel-eslint",
"globals": {
Expand Down
101 changes: 101 additions & 0 deletions app/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { app, remote } from 'electron';
import path from 'path';

const BASIC_PATH = (app || remote.app).getPath('appData');
const TEMP_DIR = process.platform === 'win32' ? 'C:\\Windows\\Temp' : '/tmp';
const IS_TEST = process.env.NODE_ENV === 'test';
const SETTING_FILE = 'store.json';

export const SETTING_FILE_PATH = !IS_TEST ?
path.join(BASIC_PATH, 'oh-my-desk', SETTING_FILE) :
path.join(TEMP_DIR, SETTING_FILE);

const ROOT_PATH = path.resolve(__dirname, '..');

function getPagePath(target) {
const ENV = process.env.NODE_ENV;
const MIDDLE_PATH = ENV === 'development' ?
path.join('app', 'renderer', 'pages', target) :
path.join('build');

return `file://${path.join(ROOT_PATH, MIDDLE_PATH, `${target}.html`)}`;
}
export const WIDGET_PATH = getPagePath('widget');
export const PREFERENCE_PATH = getPagePath('preference');
export const SEARCH_PATH = getPagePath('search');
export const UPDATE_WINDOW_PATH = getPagePath('UpdateWindow');
export const UPDATE_PROGRESS_PATH = getPagePath('UpdateProgress');

export const TRAY_ICON_PATH = path.join(ROOT_PATH, 'app', 'assets', 'iconTemplate.png');
export const LOGO_ICON_PATH = path.join(ROOT_PATH, 'app', 'assets', 'oh-my-desk-icon.png');

export const DEFAULT_SETTING = {
identification: {
widgetInfoById: {
'fb07e56a-2ef3-4c3f-b7d4-3680a7173dd2': {
size: {
height: 787,
width: 750,
},
isEditProgress: false,
isMakeProgress: false,
position: {
x: 360,
y: 83,
},
createTime: '2018-11-13T04:10:58.640Z',
name: 'google',
isOnTop: false,
url: 'https://www.google.com/',
isOpen: true,
favorites: true,
userAgent: 'DESKTOP',
resentFocusTime: '2018-11-26T11:32:48.186Z',
id: 'fb07e56a-2ef3-4c3f-b7d4-3680a7173dd2',
reloadInterval: 5,
},
'e8581480-cd58-458a-a268-f9869fa5fcfc': {
size: {
height: 777,
width: 821,
},
isEditProgress: false,
isMakeProgress: false,
position: {
x: 575,
y: 115,
},
createTime: '2018-11-13T11:32:08.049Z',
name: 'trello',
isOnTop: false,
url: 'https://trello.com',
isOpen: false,
favorites: false,
userAgent: 'DESKTOP',
resentFocusTime: '2018-11-25T16:33:47.625Z',
id: 'e8581480-cd58-458a-a268-f9869fa5fcfc',
},
'd5db9663-4879-47ca-ab63-10cf74de2967': {
size: {
height: 600,
width: 500,
},
isEditProgress: false,
isMakeProgress: false,
position: {
x: 600,
y: 99,
},
createTime: '2018-11-25T16:34:16.673Z',
name: 'translator',
isOnTop: false,
url: 'https://translate.google.com/',
isOpen: false,
favorites: false,
userAgent: 'DESKTOP',
resentFocusTime: '2018-11-25T16:34:17.266Z',
id: 'd5db9663-4879-47ca-ab63-10cf74de2967',
},
},
},
};
39 changes: 1 addition & 38 deletions app/constants/path/index.js
Original file line number Diff line number Diff line change
@@ -1,45 +1,8 @@
import { app, remote } from 'electron';
import path from 'path';

/**
* Path for globally.
*/
export const CONFIG_PATH = (app || remote.app).getPath('appData');
export const SETTING_FILE_NAME = '/oh-my-desk/store.json';

/**
* Path for main process.
*/

function getPagePath(target) {
const rootPath = process.env.NODE_ENV === 'development' ?
path.resolve(__dirname, '../../..') : path.resolve(__dirname, '..');
const projectPath = process.env.NODE_ENV === 'development' ? `app/renderer/pages/${target}` : 'build';
const htmlPath = `${target}.html`;

return path.join(rootPath, projectPath, htmlPath);
}

export const WIDGET_PATH = getPagePath('widget');
export const PREFERENCE_PATH = getPagePath('preference');
export const SEARCH_PATH = getPagePath('search');
export const UPDATE_WINDOW_PATH = getPagePath('UpdateWindow');
export const UPDATE_PROGRESS_PATH = getPagePath('UpdateProgress');

function getAssetPath(image) {
const rootPath = process.env.NODE_ENV === 'development' ?
path.resolve(__dirname, '../../..') : path.resolve(__dirname, '..');
const assetPath = 'app/assets';

return path.join(rootPath, assetPath, `${image}.png`);
}

export const TRAY_ICON_PATH = getAssetPath('iconTemplate');
export const LOGO_ICON_PATH = getAssetPath('oh-my-desk-icon');

/**
* Path for renderer process.
*/
const ROOT_PATH = process.env.NODE_ENV === 'development' ? // TODO find better method to get root path.
path.resolve(__dirname, '../../../..') : path.resolve(__dirname, '..');
export const PRELOAD_SCRIPT_PATH = path.join(ROOT_PATH, 'build/preloadScript.js');
export const PRELOAD_SCRIPT_PATH = path.join(ROOT_PATH, 'build/preloadScript.js'); // eslint-disable-line
14 changes: 14 additions & 0 deletions app/e2e-ipc-handler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { ipcMain } from 'electron';
import TrayMenuBar from 'main/utils/menu/trayMenuBar';

function e2eIpcHandler() {
ipcMain.on('search.window.open', () => {
TrayMenuBar.showWindow();
});

ipcMain.on('search.window.close', () => {
TrayMenuBar.hideWindow();
});
}

export default e2eIpcHandler;
4 changes: 2 additions & 2 deletions app/main/controllers/search.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { app, dialog } from 'electron';
import * as TYPES from 'actions/constant/actionTypes';
import TrayBar from 'main/utils/menu/trayMenuBar';
import * as PATH from 'constants/path';
import { LOGO_ICON_PATH } from 'config';
import i18n from 'constants/i18n';

const searchController = (action) => {
Expand All @@ -18,7 +18,7 @@ const searchController = (action) => {
title: text.quit,
message: text.quitMessage,
buttons: [text.ok, text.cancel],
icon: PATH.LOGO_ICON_PATH,
icon: LOGO_ICON_PATH,
};
dialog.showMessageBox(options, (index) => {
const isYesBtn = index === 0;
Expand Down
4 changes: 2 additions & 2 deletions app/main/utils/__tests__/disk/getData.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import fs from 'fs';
import * as SETTING from 'constants/setting';
import { DEFAULT_SETTING } from 'config';
import getData from 'main/utils/disk/getData';

jest.mock('fs');
Expand All @@ -22,6 +22,6 @@ describe('test getStoredDataInDisk', () => {
const result = getData();

expect(fs.readFileSync).toHaveBeenCalledTimes(0);
expect(result).toEqual(JSON.parse(SETTING.defaultWidgets));
expect(result).toEqual(DEFAULT_SETTING);
});
});
11 changes: 2 additions & 9 deletions app/main/utils/__tests__/update/openUpdateProgress.spec.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { BrowserWindow } from 'electron';
import uuid from 'uuid';
import url from 'url';
import * as PATH from 'constants/path';
import { UPDATE_PROGRESS_PATH } from 'config';
import store from 'store/storeMain';
import openUpdateProgress from 'main/utils/update/openUpdateProgress';
import { updateProgressWindowOpen, updateProgressWindowClose } from 'actions/update';
Expand Down Expand Up @@ -45,12 +44,6 @@ describe('test openUpdateProgress', () => {
openUpdateProgress();

expect(mockWindow.loadURL).toHaveBeenCalledTimes(1);
expect(mockWindow.loadURL).toHaveBeenCalledWith(
url.format({
pathname: PATH.UPDATE_PROGRESS_PATH,
protocol: 'file:',
slashes: true,
}),
);
expect(mockWindow.loadURL).toHaveBeenCalledWith(UPDATE_PROGRESS_PATH);
});
});
11 changes: 2 additions & 9 deletions app/main/utils/__tests__/update/openUpdateWindow.spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { BrowserWindow } from 'electron';
import url from 'url';
import * as PATH from 'constants/path';
import { UPDATE_WINDOW_PATH } from 'config';
import openUpdateWindow from 'main/utils/update/openUpdateWindow';

describe('test openUpdateWindow', () => {
Expand All @@ -15,12 +14,6 @@ describe('test openUpdateWindow', () => {
openUpdateWindow();

expect(mockWindow.loadURL).toHaveBeenCalledTimes(1);
expect(mockWindow.loadURL).toHaveBeenCalledWith(
url.format({
pathname: PATH.UPDATE_WINDOW_PATH,
protocol: 'file:',
slashes: true,
}),
);
expect(mockWindow.loadURL).toHaveBeenCalledWith(UPDATE_WINDOW_PATH);
});
});
9 changes: 4 additions & 5 deletions app/main/utils/__tests__/widget/makeWidget.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Immutable from 'immutable';
import * as actions from 'actions/widget';
import { BrowserWindow as MockBrowserWindow } from 'app/__mocks__/electron';
import storeMock from 'store/storeMain';
import * as PATH from 'constants/path';
import { WIDGET_PATH, LOGO_ICON_PATH } from 'config';
import * as updateWidgetContentBounds from 'main/utils/widget/updateWidgetContentBounds';
import makeWidget from 'main/utils/widget/makeWidget';

Expand Down Expand Up @@ -106,7 +106,7 @@ describe('test makeWidgetWindow', () => {
title: 'Close Widget',
message: 'Content of progress will be disappear. \nDo close making window?',
buttons: ['Ok', 'Cancel'],
icon: PATH.LOGO_ICON_PATH,
icon: LOGO_ICON_PATH,
}, expect.any(Function));
});

Expand All @@ -131,7 +131,7 @@ describe('test makeWidgetWindow', () => {
title: 'Close Widget',
message: 'Content of progress will be disappear. \nDo close making window?',
buttons: ['Ok', 'Cancel'],
icon: PATH.LOGO_ICON_PATH,
icon: LOGO_ICON_PATH,
}, expect.any(Function));
});

Expand Down Expand Up @@ -216,8 +216,7 @@ describe('test makeWidgetWindow', () => {
it('when process.env.NODE_ENV === development', () => {
makeWidget('mock-id', mockInfo);
expect(mock.loadURL).toHaveBeenCalledTimes(1);
expect(mock.loadURL)
.toHaveBeenCalledWith(`file://${PATH.WIDGET_PATH}`);
expect(mock.loadURL).toHaveBeenCalledWith(WIDGET_PATH);
});

// TODO test about process.env.NODE_ENV === 'production'
Expand Down
11 changes: 2 additions & 9 deletions app/main/utils/__tests__/window/openPreference.spec.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { BrowserWindow } from 'electron';
import Immutable from 'immutable';
import uuid from 'uuid';
import url from 'url';
import store from 'store/storeMain';
import * as PATH from 'constants/path';
import { PREFERENCE_PATH } from 'config';
import openPreference from 'main/utils/window/openPreference';
import { openBrowserWindow } from 'actions/window';
import * as preferenceActions from 'actions/preference';
Expand Down Expand Up @@ -64,13 +63,7 @@ describe('test openPreference', () => {
openPreference();

expect(mockWindow.loadURL).toHaveBeenCalledTimes(1);
expect(mockWindow.loadURL).toHaveBeenCalledWith(
url.format({
pathname: PATH.PREFERENCE_PATH,
protocol: 'file:',
slashed: true,
}),
);
expect(mockWindow.loadURL).toHaveBeenCalledWith(PREFERENCE_PATH);
});

it('should call BrowserWindow.on', () => {
Expand Down
13 changes: 7 additions & 6 deletions app/main/utils/disk/getData.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import fs from 'fs';
import * as PATH from 'constants/path';
import * as SETTING from 'constants/setting';
import {
DEFAULT_SETTING,
SETTING_FILE_PATH,
} from 'config';

const getData = () => {
const STORED_PATH = `${PATH.CONFIG_PATH}/${PATH.SETTING_FILE_NAME}`;
if (!fs.existsSync(STORED_PATH)) {
return JSON.parse(SETTING.defaultWidgets);
if (!fs.existsSync(SETTING_FILE_PATH)) {
return DEFAULT_SETTING;
}

const storedData = fs.readFileSync(STORED_PATH, { encoding: 'utf-8' });
const storedData = fs.readFileSync(SETTING_FILE_PATH, { encoding: 'utf-8' });

return JSON.parse(storedData);
};
Expand Down
4 changes: 2 additions & 2 deletions app/main/utils/disk/saveData.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import fs from 'fs';
import * as PATH from 'constants/path';
import { SETTING_FILE_PATH } from 'config';
import store from 'store/storeMain';

const saveData = () => {
const data = store.getState().get('share');

fs.writeFileSync(`${PATH.CONFIG_PATH}/${PATH.SETTING_FILE_NAME}`, JSON.stringify(data.toJS()));
fs.writeFileSync(SETTING_FILE_PATH, JSON.stringify(data.toJS()));
};

export default saveData;
5 changes: 5 additions & 0 deletions app/main/utils/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { hotKeySearchWindowSelector } from 'store/reducers/share/config/selector
import saveData from 'main/utils/disk/saveData';
import TrayMenuBar from 'main/utils/menu/trayMenuBar';
import { setInitialStore } from 'actions/setting';
import e2eIpcHandler from '../../e2e-ipc-handler';

// save data about setting every 5 minutes.
const SAVE_SETTING_INTERVAL = 300000;
Expand Down Expand Up @@ -50,6 +51,10 @@ function init() {
}

store.dispatch(setInitialStore());

if (process.env.NODE_ENV === 'test') {
e2eIpcHandler();
}
}

export default init;
Loading