Compare commits
63 Commits
Author | SHA1 | Date | |
---|---|---|---|
c406c11b88 | |||
|
083b450fd3 | ||
|
105bfa6b66 | ||
|
c4a9410e76 | ||
|
0c6fad9828 | ||
|
512a079698 | ||
|
0a75ba489a | ||
|
de49954d58 | ||
|
c5d8775d93 | ||
|
e4f83505e0 | ||
|
2d8aa8b6c7 | ||
|
f3f430ab47 | ||
|
f63522dcf1 | ||
|
3ae1535348 | ||
|
812c3a1edd | ||
|
079f0399fc | ||
|
f8d5c7c4f9 | ||
|
e35a2b69fa | ||
|
58d0251849 | ||
|
e7c99dade0 | ||
|
ec2853f2b6 | ||
|
0cbdf6b8a1 | ||
|
0a009067ae | ||
|
be3c9e17bc | ||
|
bae2d779f7 | ||
|
f71fa9d6c7 | ||
|
f9a05f42e5 | ||
|
5d315f08cb | ||
|
482cffbb4e | ||
|
25c23d161e | ||
|
7497fe7a41 | ||
|
446b730430 | ||
|
3db2da197c | ||
|
714c585f9b | ||
|
5a8a3aa04c | ||
|
5a46f07509 | ||
|
e08191e92a | ||
|
be639705f6 | ||
|
bb24e425c9 | ||
|
c414e832b0 | ||
|
7707eccbf6 | ||
|
9aa0b10e0d | ||
|
ec0c68c881 | ||
|
2250d86bc3 | ||
|
c1debf849e | ||
|
5dc3336c4b | ||
|
2b43f6444b | ||
|
beb9b92cc0 | ||
|
bf9989462f | ||
|
968a1714e7 | ||
|
b192c65423 | ||
|
8d5ef466f8 | ||
|
20e3c5caee | ||
|
2d4ea6038f | ||
|
410f795a0d | ||
|
c6dc4dbdc7 | ||
|
72038ea76c | ||
|
05f0b399bf | ||
|
3955b2e342 | ||
|
eb31b843e2 | ||
|
e64fe15a8f | ||
|
2a102c742a | ||
|
b7d16c2790 |
@ -1 +1 @@
|
||||
chrome 77
|
||||
chrome 84
|
||||
|
164
.eslintrc.js
164
.eslintrc.js
@ -21,167 +21,29 @@ module.exports = {
|
||||
},
|
||||
plugins: [
|
||||
'jest',
|
||||
// required to lint *.vue files
|
||||
'vue'
|
||||
],
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:vue/recommended',
|
||||
'plugin:jest/recommended'
|
||||
'plugin:jest/recommended',
|
||||
'plugin:vuejs-accessibility/recommended',
|
||||
'tjw-base',
|
||||
'tjw-vue'
|
||||
],
|
||||
rules: {
|
||||
'arrow-parens': ['off'],
|
||||
'brace-style': [
|
||||
'no-restricted-syntax': [
|
||||
'error',
|
||||
'1tbs',
|
||||
{
|
||||
'allowSingleLine': true
|
||||
}
|
||||
'Property[method="true"]'
|
||||
],
|
||||
'comma-dangle': ['error', 'never'],
|
||||
'comma-spacing': [
|
||||
'vuejs-accessibility/label-has-for': [
|
||||
'error',
|
||||
{
|
||||
'before': false,
|
||||
'after': true
|
||||
'components': ['Label'],
|
||||
'required': {
|
||||
'some': ['nesting', 'id']
|
||||
},
|
||||
'allowChildren': false
|
||||
}
|
||||
],
|
||||
'comma-style': ['error', 'last'],
|
||||
'curly': ['error'],
|
||||
// allow async-await
|
||||
'generator-star-spacing': ['off'],
|
||||
// 2 space indentation to match .editorconfig
|
||||
'indent': [
|
||||
'error',
|
||||
2,
|
||||
{
|
||||
'SwitchCase': 1
|
||||
}
|
||||
],
|
||||
'keyword-spacing': [
|
||||
'error',
|
||||
{
|
||||
'before': true,
|
||||
'after': true
|
||||
}
|
||||
],
|
||||
// allow debugger during development
|
||||
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
|
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
|
||||
'no-multi-spaces': ['error'],
|
||||
'no-restricted-syntax': ['error', 'Property[method="true"]'],
|
||||
'no-unused-vars': ['error'],
|
||||
'no-undef': ['error'],
|
||||
// Only allow let and const, no var
|
||||
'no-var': ['error'],
|
||||
'object-curly-spacing': ['error', 'always'],
|
||||
'one-var': ['error', 'never'],
|
||||
'quotes': ['error', 'single'],
|
||||
'semi': ['error', 'always'],
|
||||
'space-before-blocks': ['error', 'always'],
|
||||
'space-before-function-paren': ['error', 'always'],
|
||||
'space-in-parens': ['error', 'never'],
|
||||
'space-infix-ops': ['error'],
|
||||
'spaced-comment': ['error', 'always'],
|
||||
// Vue Linter Options
|
||||
'vue/attribute-hyphenation': ['error', 'never'],
|
||||
'vue/attributes-order': [
|
||||
'error',
|
||||
{
|
||||
'order': [
|
||||
// 'v-for item in items'
|
||||
'LIST_RENDERING',
|
||||
// 'v-if', 'v-else-if', 'v-else', 'v-show', 'v-cloak'
|
||||
'CONDITIONALS',
|
||||
// 'v-once', 'v-pre'
|
||||
'RENDER_MODIFIERS',
|
||||
// 'v-model', 'v-bind', ':property="foo"'
|
||||
'BINDING',
|
||||
// 'v-text', 'v-html'
|
||||
'CONTENT',
|
||||
// 'is'
|
||||
'DEFINITION',
|
||||
// 'id'
|
||||
'GLOBAL',
|
||||
// 'customProp="foo"', 'class', 'type', 'value' etc
|
||||
'OTHER_ATTR',
|
||||
// '@click="functionCall"', 'v-on="event"'
|
||||
'EVENTS',
|
||||
// 'slot', 'key', 'ref'
|
||||
'UNIQUE'
|
||||
]
|
||||
}
|
||||
],
|
||||
'vue/html-closing-bracket-newline': [
|
||||
'error',
|
||||
{
|
||||
'singleline': 'never',
|
||||
'multiline': 'always'
|
||||
}
|
||||
],
|
||||
'vue/html-closing-bracket-spacing': [
|
||||
'error',
|
||||
{
|
||||
'startTag': 'never',
|
||||
'endTag': 'never',
|
||||
'selfClosingTag': 'always'
|
||||
}
|
||||
],
|
||||
'vue/html-indent': [
|
||||
'error',
|
||||
2,
|
||||
{
|
||||
'attribute': 1,
|
||||
'closeBracket': 0
|
||||
}
|
||||
],
|
||||
'vue/html-self-closing': [
|
||||
'error',
|
||||
{
|
||||
'html': {
|
||||
'void': 'always',
|
||||
'normal': 'never',
|
||||
'component': 'always'
|
||||
}
|
||||
}
|
||||
],
|
||||
'vue/max-attributes-per-line': [
|
||||
'error',
|
||||
{
|
||||
'singleline': 3,
|
||||
'multiline': {
|
||||
'max': 1,
|
||||
'allowFirstLine': false
|
||||
}
|
||||
}
|
||||
],
|
||||
'vue/name-property-casing': ['error', 'PascalCase'],
|
||||
'vue/order-in-components': [
|
||||
'error',
|
||||
{
|
||||
'order': [
|
||||
'el',
|
||||
'name',
|
||||
['template', 'render'],
|
||||
'parent',
|
||||
'functional',
|
||||
['delimiters', 'comments'],
|
||||
['components', 'directives'],
|
||||
'extends',
|
||||
'mixins',
|
||||
'inheritAttrs',
|
||||
'model',
|
||||
['props', 'propsData'],
|
||||
'data',
|
||||
'methods',
|
||||
'computed',
|
||||
'filters',
|
||||
'watch',
|
||||
'LIFECYCLE_HOOKS',
|
||||
'renderError'
|
||||
]
|
||||
}
|
||||
],
|
||||
'vue/prop-name-casing': ['error', 'camelCase']
|
||||
]
|
||||
}
|
||||
};
|
||||
|
9
.travis.yml
Normal file
9
.travis.yml
Normal file
@ -0,0 +1,9 @@
|
||||
sudo: required
|
||||
dist: trusty
|
||||
language: node_js
|
||||
node_js:
|
||||
- "10"
|
||||
install:
|
||||
- npm install
|
||||
script:
|
||||
- npm run validate
|
55
CODE_OF_CONDUCT.md
Normal file
55
CODE_OF_CONDUCT.md
Normal file
@ -0,0 +1,55 @@
|
||||
# "No Ideologies" Code of Conduct
|
||||
|
||||
The following are the guidelines we expect our community members and maintainers to follow.
|
||||
|
||||
* * *
|
||||
|
||||
## Terminology and Scope
|
||||
|
||||
**What defines a "maintainer"?**
|
||||
|
||||
* A maintainer is anyone that interacts with the community on behalf of this project. Amount of code written is not a qualifier. A maintainer may include those who solely help in support roles such as in resolving issues, improving documentation, administrating or moderating forums/chatrooms, or any other non-coding specific roles. Maintainers also include those that are responsible for the building and upkeep of the project.
|
||||
|
||||
**What defines a "community member"?**
|
||||
|
||||
* Anyone interacting with this project directly, including maintainers.
|
||||
|
||||
**What is the scope of these guidelines?**
|
||||
|
||||
* These guidelines apply only to this project and forms of communication directly related to it, such as issue trackers, forums, chatrooms, and in person events specific to this project. If a member is violating these guidelines outside of this project or on other platforms, that is beyond our scope and any grievances should be handled on those platforms.
|
||||
|
||||
**Discussing the guidelines:**
|
||||
|
||||
* Discussions around these guidelines, improving, updating, or altering them, is permitted so long as the discussions do not violate any existing guidelines.
|
||||
|
||||
* * *
|
||||
|
||||
## Guidelines
|
||||
|
||||
### Guidelines for community members
|
||||
|
||||
This project is technical in nature and not based around any particular non-technical ideology. As such, communication that is based primarily around ideologies unrelated to the technologies used by this repository are not permitted.
|
||||
|
||||
Any discussion or communication that is primarily focused around an ideology, be it about race, gender, politics, religion, or anything else non-technical, is not allowed. Everyone has their own ideological preferences, beliefs, and opinions. We do not seek to marginalize, exclude, or judge anyone for their ideologies. To prevent conflict between those with differing or opposing ideologies, all communication on these subjects are prohibited. Some discussions around these topics may be important, however this project is not the proper channel for these discussions.
|
||||
|
||||
### Guidelines for maintainers
|
||||
|
||||
* Maintainers must abide by the same rules as all other community members mentioned above. However, in addition, maintainers are held to a higher standard, explained below.
|
||||
* Maintainers should answer all questions politely.
|
||||
* If someone is upset or angry about something, it's probably because it's difficult to use, so thank them for bringing it to your attention and address ways to solve the problem. Maintainers should focus on the content of the message, and not on how it was delivered.
|
||||
* A maintainer should seek to update members when an issue they brought up is resolved.
|
||||
|
||||
* * *
|
||||
|
||||
## Appropriate response to violations
|
||||
|
||||
How to respond to a community member or maintainer violating a guideline.
|
||||
|
||||
1. If an issue is created that violates a guideline a maintainer should close and lock the issue, explaining "This issue is in violation of our code of conduct. Please review it before posting again." with a link to this document.
|
||||
1. If a member repeatedly violates the guidelines established in this document, they should be politely warned that continuing to violate the rules may result in being banned from the community. This means revoking access and support to interactions relating directly to the project (issue trackers, chatrooms, forums, in person events, etc.). However, they may continue to use the technology in accordance with its license.
|
||||
1. If a maintainer is in violation of a guideline, they should be informed of such with a link to this document. If additional actions are required of the maintainer but not taken, then other maintainers should be informed of these inactions.
|
||||
1. If a maintainer repeatedly violates the guidelines established in this document, they should be politely warned that continuing to violate the rules may result in being banned from the community. This means revoking access and support to interactions relating directly to the project (issue trackers, chatrooms, forums, in person events, etc.). However, they may continue to use the technology in accordance with its license. In addition, future contributions to this project may be ignored as well.
|
||||
|
||||
* * *
|
||||
|
||||
Based on version 1.0.3 from https://github.com/CodifiedConduct/coc-no-ideologies
|
46
README.md
46
README.md
@ -1,24 +1,35 @@
|
||||
# nw-vue-cli-example
|
||||
|
||||
NW.js + Vue-CLI 3 example
|
||||
[](https://travis-ci.org/nwutils/nw-vue-cli-example)
|
||||
|
||||
NW.js + Vue-CLI 4 example
|
||||
|
||||

|
||||
|
||||
* NW.js
|
||||
* Vue-CLI 3
|
||||
* Vue 2
|
||||
* Vue-DevTools
|
||||
* NW.js 0.47.0
|
||||
* Chrome 84
|
||||
* Node 14.5.0
|
||||
* Vue-CLI 4.4.6
|
||||
* Vue 2.6.11
|
||||
* Vue-DevTools (latest)
|
||||
* Babel
|
||||
* ESLint
|
||||
* Vue Linting
|
||||
* A11Y Linting
|
||||
* Jest Linting
|
||||
* Jest (100% test coverage)
|
||||
* Jest Serializer Vue (TJW)
|
||||
|
||||
*Why not include Vue-Router or Vuex?*
|
||||
|
||||
Those are both very easily added from the Vue-CLI. There is also no custom styling libraries (Bulma, Bootstrap, etc), or meta-languages (Sass, TS, Pug, etc), or component libraries (Vuetify, Inkline, etc). This repo is meant to be the "go to" option for building all desktop apps with Vue. So it avoids pushing any particular choices on to you. With the exception of testing being set up for Jest, and Linting being set up to ensure minumum quality of this boilerplate repo itself. Both of which can be easily modified, ignored, or removed.
|
||||
|
||||
|
||||
## Running Locally for development
|
||||
|
||||
1. `npm install`
|
||||
1. `npm start`
|
||||
1. An empty window will pop up while Webpack warm ups
|
||||
1. Once Webpack is running, refresh the window and you're golden
|
||||
1. Once Webpack finishes starting up your app will appear in a window
|
||||
|
||||
|
||||
## Building for distribution
|
||||
@ -31,7 +42,7 @@ NW.js + Vue-CLI 3 example
|
||||
|
||||
# **IMPORTANT NOTE ABOUT BUILDS!!!**
|
||||
|
||||
They take a long time. If you do `npm run build` expect it to take 10-30 minutes (depending on amount of dependencies in the dist and your CPU/internet). This can be adjusted by changing the build params in the `package.json`. The more platforms and build types, the longer it takes.
|
||||
They take a long time. If you do `npm run build` expect it to take 10-30 minutes. This can be adjusted by changing the build params in the `package.json`. The more platforms and build types, the longer it takes. You can also remove the `--concurrent` from the `build:nw` script to see a status of what has been completed. This will allow individual pieces to finish faster, but the entire build will take longer.
|
||||
|
||||
|
||||
## Automated quality enforcment
|
||||
@ -51,6 +62,16 @@ Want Vue-Router? Vuex? Use the Vue-CLI to add them:
|
||||
* * *
|
||||
|
||||
|
||||
## Updating Vue-DevTools
|
||||
|
||||
To update your version of Vue-DevTools run `npm run update:vue-devtools`.
|
||||
|
||||
This will download the source code for the latest version of Vue-DevTools and do a custom build for NW.js. This ensures you always have the latest version.
|
||||
|
||||
|
||||
* * *
|
||||
|
||||
|
||||
## Alternatives
|
||||
|
||||
* [nwjs-vue](https://github.com/elegantweb/nwjs-vue) - Uses Vue-CLI 2
|
||||
@ -65,7 +86,10 @@ Want Vue-Router? Vuex? Use the Vue-CLI to add them:
|
||||
This is not for those *using* this repo, but for those *maintaining* it.
|
||||
|
||||
1. When updating the version of NW.js devDependency, also update these:
|
||||
* `tests/unit/setup.js`
|
||||
* `tests/unit/components/__snapshots__/HelloWorld.test.js.snap`
|
||||
* `.browserslistrc`
|
||||
* `package.json` devDeps, build nwVersion
|
||||
* `tests/unit/setup.js`
|
||||
* `tests/unit/components/__snapshots__/HelloWorld.test.js.snap`
|
||||
* `.browserslistrc`
|
||||
1. Update the version numbers at the top of the README
|
||||
1. Bump the version number, and all the npm scripts that reference the version number
|
||||
1. Run `npm run regression` after updating dependencies or other major changes to verify builds still work correctly
|
||||
|
@ -1,5 +1,5 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
'@vue/app'
|
||||
'@vue/cli-plugin-babel/preset'
|
||||
]
|
||||
};
|
||||
|
@ -2,45 +2,20 @@ process.env.VUE_CLI_BABEL_TARGET_NODE = true;
|
||||
process.env.VUE_CLI_BABEL_TRANSPILE_MODULES = true;
|
||||
|
||||
module.exports = {
|
||||
collectCoverageFrom: [
|
||||
'src/**/*.{js,vue}',
|
||||
'!src/main.js',
|
||||
'!**/node_modules/**'
|
||||
],
|
||||
preset: '@vue/cli-plugin-unit-jest',
|
||||
coverageDirectory: '<rootDir>/tests/unit/coverage',
|
||||
moduleFileExtensions: [
|
||||
'js',
|
||||
'jsx',
|
||||
'json',
|
||||
'vue'
|
||||
],
|
||||
moduleNameMapper: {
|
||||
'^@/(.*)$': '<rootDir>/src/$1'
|
||||
},
|
||||
setupFilesAfterEnv: [
|
||||
'<rootDir>/tests/unit/setup.js'
|
||||
],
|
||||
snapshotSerializers: [
|
||||
'<rootDir>/tests/unit/serializer.js'
|
||||
'<rootDir>/node_modules/jest-serializer-vue-tjw'
|
||||
],
|
||||
testEnvironment: 'jest-environment-jsdom-global',
|
||||
testMatch: [
|
||||
'**/tests/unit/**/*.test.js'
|
||||
],
|
||||
testPathIgnorePatterns: [
|
||||
'<rootDir>/tests/e2e'
|
||||
],
|
||||
testURL: 'http://localhost/',
|
||||
transform: {
|
||||
'^.+\\.vue$': 'vue-jest',
|
||||
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub',
|
||||
'^.+\\.jsx?$': 'babel-jest'
|
||||
},
|
||||
transformIgnorePatterns: [
|
||||
'/node_modules/'
|
||||
],
|
||||
watchPlugins: [
|
||||
'jest-watch-typeahead/filename',
|
||||
'jest-watch-typeahead/testname'
|
||||
'<rootDir>/tests/e2e',
|
||||
'<rootDir>/dist',
|
||||
'<rootDir>/dist-vue'
|
||||
]
|
||||
};
|
||||
|
@ -15,6 +15,7 @@ nwBinary = './node_modules/nw/' + nwBinary;
|
||||
driver = './node_modules/nw/' + driver;
|
||||
|
||||
module.exports = (function (settings) {
|
||||
console.log(nwBinary);
|
||||
settings.webdriver.server_path = driver;
|
||||
settings.selenium.cli_args['webdriver.chrome.driver'] = driver;
|
||||
return settings;
|
||||
|
15663
package-lock.json
generated
15663
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
135
package.json
135
package.json
@ -1,73 +1,75 @@
|
||||
{
|
||||
"name": "nw-vue",
|
||||
"version": "1.0.0",
|
||||
"main": "http://localhost:8964",
|
||||
"node-remote": "http://localhost:8964",
|
||||
"node-main": "",
|
||||
"window": {
|
||||
"width": 960,
|
||||
"height": 600,
|
||||
"min_width": 700,
|
||||
"min_height": 500,
|
||||
"icon": "src/assets/vue.png"
|
||||
},
|
||||
"version": "1.6.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "concurrently \"npm run serve\" \"wait-on http://localhost:8964 && nw .\"",
|
||||
"serve": "vue-cli-service serve --port=8964",
|
||||
"build": "npm run build:clean && npm run build:vue && npm run build:nw",
|
||||
"build:clean": "rimraf ./dist-vue ./dist",
|
||||
"build:vue": "vue-cli-service build --modern --dest ./dist-vue",
|
||||
"build:nw": "build --concurrent --tasks win-x86,linux-x86,linux-x64,mac-x64 --mirror https://dl.nwjs.io/ .",
|
||||
"build:win": "npm run build:win:clean && npm run build:vue && build --tasks win-x86 --mirror https://dl.nwjs.io/ .",
|
||||
"build:win:clean": "rimraf ./dist-vue ./dist/nw-vue-1.0.0-win-x86 ./dist/nw-vue-1.0.0-win-x86.zip ./dist/nw-vue-1.0.0-win-x86.7z ./dist/nw-vue-1.0.0-win-x86-Setup.exe",
|
||||
"run:win": "dist\\nw-vue-1.0.0-win-x86\\nw-vue.exe",
|
||||
"regression": "rd /s /q node_modules & rd /s /q node_modules & rd /s /q node_modules & npm install && npm run lint && npm test && npm run build:win && npm run run:win",
|
||||
"lint": "vue-cli-service lint --no-fix",
|
||||
"fix": "vue-cli-service lint --fix",
|
||||
"test": "npm run test:unit",
|
||||
"test:unit": "jest --config jest.config.js --coverage",
|
||||
"test:e2e": "vue-cli-service test:e2e",
|
||||
"test:unit": "jest --config jest.config.js --coverage --runInBand"
|
||||
"lint": "vue-cli-service lint --no-fix",
|
||||
"build:clean": "rimraf ./dist-vue ./dist",
|
||||
"build:lin": "npm run build:lin:clean && npm run build:vue && build --tasks linux-x64 --mirror https://dl.nwjs.io/ .",
|
||||
"build:lin:clean": "rimraf ./dist-vue ./dist/nw-vue-1.6.0-linux-x64 ./dist/nw-vue-1.6.0-linux-x64.zip",
|
||||
"build:nw": "build --concurrent --tasks win-x86,linux-x86,linux-x64,mac-x64 --mirror https://dl.nwjs.io/ .",
|
||||
"build:vue": "vue-cli-service build --modern --dest ./dist-vue",
|
||||
"build:win": "npm run build:win:clean && npm run build:vue && build --tasks win-x86 --mirror https://dl.nwjs.io/ .",
|
||||
"build:win:clean": "rimraf ./dist-vue ./dist/nw-vue-1.6.0-win-x86 ./dist/nw-vue-1.6.0-win-x86.zip ./dist/nw-vue-1.6.0-win-x86.7z ./dist/nw-vue-1.6.0-win-x86-Setup.exe",
|
||||
"fix": "vue-cli-service lint --fix",
|
||||
"regression": "rd /s /q node_modules & rd /s /q node_modules & rd /s /q node_modules & npm install && npm run lint && npm test && npm run build:win && npm run run:win",
|
||||
"run:lin": "./dist/nw-vue-1.6.0-linux-x64/nw-vue",
|
||||
"run:win": "dist\\nw-vue-1.6.0-win-x86\\nw-vue.exe",
|
||||
"start": "concurrently \"npm run serve\" \"wait-on http://localhost:8964 && nw .\"",
|
||||
"test": "npm run test:unit",
|
||||
"update:vue-devtools": "rimraf ./node_modules/nw-vue-devtools-prebuilt && npm install",
|
||||
"validate": "npm run lint && npm run test:unit && npm run build:vue"
|
||||
},
|
||||
"main": "http://localhost:8964",
|
||||
"dependencies": {
|
||||
"express": "^4.17.1"
|
||||
"bootstrap": "^4.5.0",
|
||||
"bootstrap-vue": "^2.16.0",
|
||||
"express": "^4.17.1",
|
||||
"vue-router": "^3.2.0",
|
||||
"vue-select": "^3.10.7",
|
||||
"vue2-datepicker": "^3.6.1",
|
||||
"vuex": "^3.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-plugin-babel": "^3.11.0",
|
||||
"@vue/cli-plugin-e2e-nightwatch": "^3.11.0",
|
||||
"@vue/cli-plugin-eslint": "^3.11.0",
|
||||
"@vue/cli-plugin-unit-jest": "^3.11.0",
|
||||
"@vue/cli-service": "^3.11.0",
|
||||
"@vue/test-utils": "1.0.0-beta.29",
|
||||
"babel-core": "7.0.0-bridge.0",
|
||||
"babel-eslint": "^10.0.3",
|
||||
"babel-jest": "^24.9.0",
|
||||
"babel-plugin-dynamic-import-node": "^2.3.0",
|
||||
"babel-plugin-transform-runtime": "^6.23.0",
|
||||
"babel-preset-env": "^1.7.0",
|
||||
"babel-preset-stage-2": "^6.24.1",
|
||||
"babel-preset-vue-app": "^2.0.0",
|
||||
"concurrently": "^4.1.2",
|
||||
"core-js": "^2.6.5",
|
||||
"eslint": "^6.4.0",
|
||||
"eslint-plugin-jest": "^22.17.0",
|
||||
"eslint-plugin-vue": "^5.2.3",
|
||||
"jest": "^24.9.0",
|
||||
"jest-environment-jsdom-global": "^1.2.0",
|
||||
"jest-transform-stub": "^2.0.0",
|
||||
"nw": "0.41.1-sdk",
|
||||
"nw-vue-devtools": "^1.3.0",
|
||||
"@vue/cli-plugin-babel": "^4.4.6",
|
||||
"@vue/cli-plugin-e2e-nightwatch": "^4.4.6",
|
||||
"@vue/cli-plugin-eslint": "^4.4.6",
|
||||
"@vue/cli-plugin-router": "^4.4.6",
|
||||
"@vue/cli-plugin-unit-jest": "^4.4.6",
|
||||
"@vue/cli-plugin-vuex": "^4.4.6",
|
||||
"@vue/cli-service": "^4.4.6",
|
||||
"@vue/test-utils": "^1.0.3",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"concurrently": "^5.2.0",
|
||||
"core-js": "^3.6.5",
|
||||
"eslint": "^7.4.0",
|
||||
"eslint-config-tjw-base": "^1.0.0",
|
||||
"eslint-config-tjw-vue": "^2.0.0",
|
||||
"eslint-plugin-jest": "^23.18.0",
|
||||
"eslint-plugin-vue": "^6.2.2",
|
||||
"eslint-plugin-vuejs-accessibility": "^0.3.1",
|
||||
"jest-serializer-vue-tjw": "^3.14.0",
|
||||
"nw": "0.47.0-sdk",
|
||||
"nw-vue-devtools-prebuilt": "^0.0.10",
|
||||
"nwjs-builder-phoenix": "^1.15.0",
|
||||
"nwjs-types": "^1.0.0",
|
||||
"rimraf": "^3.0.0",
|
||||
"vue": "^2.6.10",
|
||||
"vue-jest": "^3.0.5",
|
||||
"vue-template-compiler": "^2.6.10",
|
||||
"wait-on": "^3.3.0"
|
||||
"rimraf": "^3.0.2",
|
||||
"vue": "^2.6.11",
|
||||
"vue-template-compiler": "^2.6.11",
|
||||
"wait-on": "^5.1.0"
|
||||
},
|
||||
"chromium-args": "--load-extension='./node_modules/nw-vue-devtools/extension'",
|
||||
"ManifestComments": [
|
||||
"Only add dependencies that you want shipped to the end user, for everything else, use devDependencies, including things that will be bundled by webpack.",
|
||||
"NW.js requires a name and a main, everything else is optional.",
|
||||
"The build section is used by nwjs-builder-phoenix, see its documentation for more info",
|
||||
"To turn spell checking off, remove it from the chromium-args in this file"
|
||||
],
|
||||
"build": {
|
||||
"nwVersion": "v0.41.1",
|
||||
"nwVersion": "v0.47.0",
|
||||
"nwFlavor": "normal",
|
||||
"targets": [
|
||||
"zip",
|
||||
@ -89,6 +91,7 @@
|
||||
".gitignore",
|
||||
".editorconfig",
|
||||
"babel.config.js",
|
||||
"CODE_OF_CONDUCT.md",
|
||||
"cypress.json",
|
||||
"jest.config.js",
|
||||
"nightwatch.conf.js",
|
||||
@ -100,7 +103,7 @@
|
||||
"vue.config.js"
|
||||
],
|
||||
"strippedProperties": [
|
||||
"chromium-args",
|
||||
"ManifestComments",
|
||||
"scripts",
|
||||
"devDependencies",
|
||||
"build"
|
||||
@ -108,7 +111,15 @@
|
||||
"overriddenProperties": {
|
||||
"main": "http://localhost:8965",
|
||||
"node-remote": "http://localhost:8965",
|
||||
"node-main": "server.js"
|
||||
"node-main": "server.js",
|
||||
"chromium-args": "--enable-spell-checking",
|
||||
"window": {
|
||||
"width": 960,
|
||||
"height": 600,
|
||||
"min_width": 700,
|
||||
"min_height": 500,
|
||||
"icon": "dist-vue/icon.png"
|
||||
}
|
||||
},
|
||||
"win": {
|
||||
"icon": "public/icon-256.ico"
|
||||
@ -125,5 +136,15 @@
|
||||
"diffUpdaters": false,
|
||||
"hashCalculation": true
|
||||
}
|
||||
},
|
||||
"chromium-args": "--enable-spell-checking --load-extension='./node_modules/nw-vue-devtools-prebuilt/extension'",
|
||||
"node-main": "",
|
||||
"node-remote": "http://localhost:8964",
|
||||
"window": {
|
||||
"width": 960,
|
||||
"height": 600,
|
||||
"min_width": 700,
|
||||
"min_height": 500,
|
||||
"icon": "src/assets/vue.png"
|
||||
}
|
||||
}
|
||||
|
74
src/App.vue
74
src/App.vue
@ -1,41 +1,55 @@
|
||||
<template>
|
||||
<div id="app">
|
||||
<img
|
||||
src="@/assets/vue.png"
|
||||
alt="Vue.js logo"
|
||||
title="Vue.js"
|
||||
class="logo"
|
||||
/>
|
||||
<img
|
||||
src="@/assets/nw.png"
|
||||
alt="NW.js logo"
|
||||
title="NW.js"
|
||||
class="logo"
|
||||
/>
|
||||
<HelloWorld msg="Welcome to your Vue.js Desktop App in NW.js!" />
|
||||
<b-navbar toggleable="lg" type="dark" variant="info">
|
||||
<b-button class="mr-4" v-b-toggle.sidebar>Menu</b-button>
|
||||
<b-navbar-brand href="#">NavBar</b-navbar-brand>
|
||||
</b-navbar>
|
||||
<b-sidebar id="sidebar" title="Main Menu">
|
||||
<div class="px-3 py-2">
|
||||
<b-list-group>
|
||||
<b-list-group-item href="/#/">
|
||||
Hours Log
|
||||
</b-list-group-item>
|
||||
<b-list-group-item href="/#/projects">
|
||||
Projects
|
||||
</b-list-group-item>
|
||||
</b-list-group>
|
||||
<div class="dropdown-divider"></div>
|
||||
<b-list-group class="">
|
||||
<b-list-group-item href="/">
|
||||
Exports
|
||||
</b-list-group-item>
|
||||
<b-list-group-item href="/">
|
||||
Settings
|
||||
</b-list-group-item>
|
||||
</b-list-group>
|
||||
</div>
|
||||
</b-sidebar>
|
||||
<div id="nav">
|
||||
</div>
|
||||
<router-view />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import HelloWorld from '@/components/HelloWorld.vue';
|
||||
|
||||
export default {
|
||||
name: 'App',
|
||||
components: {
|
||||
HelloWorld
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#app {
|
||||
margin-top: 60px;
|
||||
color: #2C3E50;
|
||||
font-family: 'Avenir', sans-serif;
|
||||
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-align: center;
|
||||
color: #2c3e50;
|
||||
}
|
||||
.logo {
|
||||
max-height: 140px;
|
||||
margin: 0px 10px;
|
||||
|
||||
#nav {
|
||||
padding: 30px;
|
||||
}
|
||||
|
||||
#nav a {
|
||||
font-weight: bold;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
#nav a.router-link-exact-active {
|
||||
color: #42b983;
|
||||
}
|
||||
</style>
|
||||
|
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.7 KiB |
85
src/components/FsExample.vue
Normal file
85
src/components/FsExample.vue
Normal file
@ -0,0 +1,85 @@
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="error">
|
||||
There was an error attempting to read from the file system.
|
||||
</div>
|
||||
|
||||
<button
|
||||
data-test="fs-example-button"
|
||||
@click="getCurrentDirectory"
|
||||
>
|
||||
<template v-if="!error">
|
||||
Click for File System example
|
||||
</template>
|
||||
<template v-else>
|
||||
Try again for File System example
|
||||
</template>
|
||||
</button>
|
||||
|
||||
<template v-if="contents">
|
||||
<p>
|
||||
The contents of the current working directory:
|
||||
</p>
|
||||
<div class="contents">
|
||||
<div
|
||||
v-for="(file, fileIndex) in contents"
|
||||
class="file"
|
||||
:key="'file' + fileIndex"
|
||||
>
|
||||
{{ file }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'FsExample',
|
||||
data: function () {
|
||||
return {
|
||||
contents: null,
|
||||
error: false
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
getCurrentDirectory: function () {
|
||||
const fs = window.nw.require('fs');
|
||||
try {
|
||||
this.contents = fs.readdirSync('.');
|
||||
this.error = false;
|
||||
} catch (err) {
|
||||
this.error = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
button {
|
||||
background: linear-gradient(0deg, #2EB277, #65E6AC);
|
||||
border-width: 3.4px;
|
||||
border-color: #35495E;
|
||||
border-radius: 8px;
|
||||
margin: 22px 0px 6px 0px;
|
||||
padding: 11px 17px;
|
||||
color: #050709;
|
||||
font-family: 'Trebuchet MS', Verdana, sans-serif;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.contents {
|
||||
display: flex;
|
||||
flex-flow: wrap;
|
||||
}
|
||||
.file {
|
||||
flex-grow: 1;
|
||||
min-width: 200px;
|
||||
background: #DDD;
|
||||
margin: 5px;
|
||||
padding: 11px;
|
||||
}
|
||||
</style>
|
@ -37,17 +37,23 @@
|
||||
|
||||
<h3>Ecosystem</h3>
|
||||
<LinkList :links="ecosystemLinks" />
|
||||
|
||||
<hr />
|
||||
|
||||
<FsExample />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Vue from 'vue';
|
||||
|
||||
import FsExample from '@/components/FsExample.vue';
|
||||
import LinkList from '@/components/LinkList.vue';
|
||||
|
||||
export default {
|
||||
name: 'HelloWorld',
|
||||
components: {
|
||||
FsExample,
|
||||
LinkList
|
||||
},
|
||||
props: {
|
||||
@ -157,7 +163,7 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
devMode: function () {
|
||||
return window.process.env.NODE_ENV === 'development';
|
||||
return window.process.versions['nw-flavor'] === 'sdk';
|
||||
},
|
||||
versions: function () {
|
||||
return window.process.versions;
|
||||
|
19
src/main.js
19
src/main.js
@ -1,10 +1,29 @@
|
||||
import Vue from 'vue';
|
||||
import { BootstrapVue, IconsPlugin } from 'bootstrap-vue'
|
||||
import vSelect from 'vue-select'
|
||||
import DatePicker from 'vue2-datepicker'
|
||||
|
||||
import 'bootstrap/dist/css/bootstrap.css'
|
||||
import 'bootstrap-vue/dist/bootstrap-vue.css'
|
||||
import 'vue-select/dist/vue-select.css'
|
||||
import 'vue2-datepicker/index.css'
|
||||
|
||||
import App from './App.vue';
|
||||
import router from './router';
|
||||
import store from './store';
|
||||
|
||||
Vue.use(BootstrapVue)
|
||||
Vue.use(IconsPlugin)
|
||||
Vue.component('v-select', vSelect)
|
||||
Vue.component('date-picker', DatePicker)
|
||||
|
||||
Vue.config.productionTip = false;
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const app = new Vue({
|
||||
router,
|
||||
store,
|
||||
|
||||
render: function (hyperscript) {
|
||||
return hyperscript(App);
|
||||
}
|
||||
|
31
src/router/index.js
Normal file
31
src/router/index.js
Normal file
@ -0,0 +1,31 @@
|
||||
import Vue from 'vue';
|
||||
import VueRouter from 'vue-router';
|
||||
import HoursLog from '../views/HoursLog.vue';
|
||||
import TimeEntry from '../views/TimeEntry.vue';
|
||||
import Projects from '../views/Projects.vue'
|
||||
|
||||
Vue.use(VueRouter);
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: '/',
|
||||
name: 'HoursLog',
|
||||
component: HoursLog
|
||||
},
|
||||
{
|
||||
path: '/add-time-entry',
|
||||
name: 'TimeEntry',
|
||||
component: TimeEntry
|
||||
},
|
||||
{
|
||||
path: '/projects',
|
||||
name: 'Projects',
|
||||
component: Projects
|
||||
},
|
||||
];
|
||||
|
||||
const router = new VueRouter({
|
||||
routes
|
||||
});
|
||||
|
||||
export default router;
|
15
src/store/index.js
Normal file
15
src/store/index.js
Normal file
@ -0,0 +1,15 @@
|
||||
import Vue from 'vue';
|
||||
import Vuex from 'vuex';
|
||||
|
||||
Vue.use(Vuex);
|
||||
|
||||
export default new Vuex.Store({
|
||||
state: {
|
||||
},
|
||||
mutations: {
|
||||
},
|
||||
actions: {
|
||||
},
|
||||
modules: {
|
||||
}
|
||||
});
|
46
src/views/HoursLog.vue
Normal file
46
src/views/HoursLog.vue
Normal file
@ -0,0 +1,46 @@
|
||||
<template>
|
||||
<b-container class="hours-log-page">
|
||||
<b-row>
|
||||
<b-col cm="8" offset-sm="2">
|
||||
<b-row class="mt-5 mb-4 ">
|
||||
<b-col>
|
||||
<h1>Hours Log</h1>
|
||||
</b-col>
|
||||
<b-col>
|
||||
<b-btn variant="primary" @click="$router.push({name: 'TimeEntry'})">
|
||||
+ Add Entry
|
||||
</b-btn>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-row>
|
||||
<b-col>
|
||||
<b-table striped hover :items="items"></b-table>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-container>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// @ is an alias to /src
|
||||
|
||||
export default {
|
||||
name: 'HoursLog',
|
||||
components: {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
items: [
|
||||
{
|
||||
project_name: 'Company #1',
|
||||
date: 'May 12, 2020',
|
||||
start_time: '7:00 am',
|
||||
end_time: '11:00',
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
39
src/views/Projects.vue
Normal file
39
src/views/Projects.vue
Normal file
@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<b-container class="projects-page">
|
||||
<b-row>
|
||||
<b-col cm="8" offset-sm="2">
|
||||
<b-row class="mt-5 mb-4 ">
|
||||
<b-col>
|
||||
<h1>Projects</h1>
|
||||
</b-col>
|
||||
<b-col>
|
||||
<b-btn variant="primary">+ Add New Project</b-btn>
|
||||
</b-col>
|
||||
</b-row>
|
||||
|
||||
<b-row>
|
||||
<b-col>
|
||||
<v-select
|
||||
:options="[{label: 'Canada', code: 'ca'}]"
|
||||
/>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-container>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// @ is an alias to /src
|
||||
|
||||
export default {
|
||||
name: 'Projects',
|
||||
components: {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
56
src/views/TimeEntry.vue
Normal file
56
src/views/TimeEntry.vue
Normal file
@ -0,0 +1,56 @@
|
||||
<template>
|
||||
<b-container class="time-entry-page">
|
||||
<b-row>
|
||||
<b-col sm="6" offset-sm="3">
|
||||
<b-row>
|
||||
<b-col>
|
||||
<h1>New Time Entry</h1>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-row>
|
||||
<b-col>
|
||||
<b-form @submit="onSubmit" @reset="onReset">
|
||||
<b-form-group id="input-group-1" label="Star Date:" label-for="input-1">
|
||||
<date-picker v-model="formData.startDate" type="datetime" />
|
||||
</b-form-group>
|
||||
|
||||
<b-form-group id="input-group-2" label="End Date:" label-for="input-2">
|
||||
<date-picker v-model="formData.endDate" type="datetime" />
|
||||
</b-form-group>
|
||||
<b-button type="submit" variant="primary">Submit</b-button>
|
||||
<b-button type="reset" variant="danger">Reset</b-button>
|
||||
</b-form>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-container>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// @ is an alias to /src
|
||||
|
||||
export default {
|
||||
name: 'TimeEntry',
|
||||
components: {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
formData: {
|
||||
startDate: {},
|
||||
endDate: {},
|
||||
notes: '',
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onSubmit() {
|
||||
|
||||
},
|
||||
onReset() {
|
||||
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
@ -5,7 +5,7 @@ describe('App.vue', () => {
|
||||
test('Render default contents', () => {
|
||||
const wrapper = shallowMount(App);
|
||||
|
||||
expect(wrapper.html())
|
||||
expect(wrapper)
|
||||
.toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
exports[`App.vue Render default contents 1`] = `
|
||||
<div id="app">
|
||||
<img src="@/assets/vue.png" alt="Vue.js logo" title="Vue.js" class="logo">
|
||||
<img src="@/assets/logo.png" alt="Vue.js logo" title="Vue.js" class="logo">
|
||||
<img src="@/assets/nw.png" alt="NW.js logo" title="NW.js" class="logo">
|
||||
<helloworld-stub msg="Welcome to your Vue.js Desktop App in NW.js!"></helloworld-stub>
|
||||
</div>
|
||||
|
45
tests/unit/components/FsExample.test.js
Normal file
45
tests/unit/components/FsExample.test.js
Normal file
@ -0,0 +1,45 @@
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
import FsExample from '@/components/FsExample.vue';
|
||||
|
||||
describe('FsExample.vue', () => {
|
||||
test('Render default contents', () => {
|
||||
const wrapper = shallowMount(FsExample);
|
||||
|
||||
expect(wrapper)
|
||||
.toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Click button', async () => {
|
||||
const wrapper = shallowMount(FsExample);
|
||||
let domButton = wrapper.find('[data-test="fs-example-button"]');
|
||||
domButton.trigger('click');
|
||||
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
expect(window.nw.require)
|
||||
.toHaveBeenCalledWith('fs');
|
||||
|
||||
expect(wrapper)
|
||||
.toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Error state', async () => {
|
||||
window.nw.require.mockImplementation((module) => {
|
||||
if (module === 'fs') {
|
||||
return new Error();
|
||||
}
|
||||
});
|
||||
|
||||
const wrapper = shallowMount(FsExample);
|
||||
let domButton = wrapper.find('[data-test="fs-example-button"]');
|
||||
domButton.trigger('click');
|
||||
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
expect(window.nw.require)
|
||||
.toHaveBeenCalledWith('fs');
|
||||
|
||||
expect(wrapper)
|
||||
.toMatchSnapshot();
|
||||
});
|
||||
});
|
@ -15,23 +15,23 @@ describe('HelloWorld.vue', () => {
|
||||
test('Render default contents', () => {
|
||||
const wrapper = mount(HelloWorld);
|
||||
|
||||
expect(wrapper.html())
|
||||
expect(wrapper)
|
||||
.toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Activate dev tools', () => {
|
||||
test('Activate dev tools', async () => {
|
||||
const wrapper = shallowMount(HelloWorld);
|
||||
|
||||
const button = wrapper.find('[data-test="toggleDevTools"]');
|
||||
|
||||
button.trigger('click');
|
||||
wrapper.vm.$nextTick();
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
expect(wrapper.find('[data-test="toggleDevTools').html())
|
||||
.toMatchSnapshot('hide');
|
||||
|
||||
button.trigger('click');
|
||||
wrapper.vm.$nextTick();
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
expect(wrapper.find('[data-test="toggleDevTools').html())
|
||||
.toMatchSnapshot('show');
|
||||
|
@ -32,7 +32,7 @@ describe('LinkList.vue', () => {
|
||||
propsData: { links: [link] }
|
||||
});
|
||||
|
||||
expect(wrapper.html())
|
||||
expect(wrapper)
|
||||
.toMatchSnapshot();
|
||||
});
|
||||
|
||||
|
43
tests/unit/components/__snapshots__/FsExample.test.js.snap
Normal file
43
tests/unit/components/__snapshots__/FsExample.test.js.snap
Normal file
@ -0,0 +1,43 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`FsExample.vue Click button 1`] = `
|
||||
<div>
|
||||
<!---->
|
||||
<button>
|
||||
Click for File System example
|
||||
</button>
|
||||
<p>
|
||||
The contents of the current working directory:
|
||||
</p>
|
||||
<div class="contents">
|
||||
<div class="file">
|
||||
example-file-1.ext
|
||||
</div>
|
||||
<div class="file">
|
||||
example-file-2.ext
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`FsExample.vue Error state 1`] = `
|
||||
<div>
|
||||
<div>
|
||||
There was an error attempting to read from the file system.
|
||||
</div>
|
||||
<button>
|
||||
Try again for File System example
|
||||
</button>
|
||||
<!---->
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`FsExample.vue Render default contents 1`] = `
|
||||
<div>
|
||||
<!---->
|
||||
<button>
|
||||
Click for File System example
|
||||
</button>
|
||||
<!---->
|
||||
</div>
|
||||
`;
|
@ -23,11 +23,11 @@ exports[`HelloWorld.vue Render default contents 1`] = `
|
||||
</h1>
|
||||
<h3>
|
||||
You are using
|
||||
Vue.js (v2.6.10),
|
||||
NW.js (v0.41.1-sdk),
|
||||
Node.js (v12.9.1),
|
||||
Vue.js (v2.6.11),
|
||||
NW.js (v0.47.0-sdk),
|
||||
Node.js (v14.5.0),
|
||||
and
|
||||
Chromium (v77.0.3865.75).
|
||||
Chromium (v84.0.4147.89).
|
||||
</h3>
|
||||
<button>
|
||||
Show
|
||||
@ -141,5 +141,13 @@ exports[`HelloWorld.vue Render default contents 1`] = `
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<hr>
|
||||
<div>
|
||||
<!---->
|
||||
<button>
|
||||
Click for File System example
|
||||
</button>
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
@ -1,42 +0,0 @@
|
||||
// Based on jest-serializer-vue
|
||||
|
||||
const beautify = require('pretty');
|
||||
|
||||
function isHtmlString (received) {
|
||||
return received && typeof(received) === 'string' && received.startsWith('<');
|
||||
}
|
||||
|
||||
function isVueWrapper (received) {
|
||||
return received && typeof(received) === 'object' && typeof(received.isVueInstance) === 'function';
|
||||
}
|
||||
|
||||
// This removes data-test="whatever" from your snapshots
|
||||
// If you also want to remove them from your production builds, see:
|
||||
// https://forum.vuejs.org/t/how-to-remove-attributes-from-tags-inside-vue-components/24138
|
||||
function removeDataTestAttributes (html) {
|
||||
// [-\w]+ will catch 1 or more instaces of a-z, A-Z, 0-9, hyphen (-), or underscore (_)
|
||||
return html.replace(/ data-test="[-\w]+"/g, '');
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
test: function (received) {
|
||||
return isHtmlString(received) || isVueWrapper(received);
|
||||
},
|
||||
print: function (received) {
|
||||
let html = received || '';
|
||||
if (isVueWrapper(received)) {
|
||||
html = received.html();
|
||||
}
|
||||
html = removeDataTestAttributes(html);
|
||||
// To see available options: https://github.com/beautify-web/js-beautify/blob/master/js/src/html/options.js
|
||||
const options = {
|
||||
indent_size: 2,
|
||||
unformatted: ['code', 'pre'],
|
||||
inline: [],
|
||||
indent_inner_html: true,
|
||||
indent_char: ' ',
|
||||
sep: '\n'
|
||||
};
|
||||
return beautify(html, options);
|
||||
}
|
||||
};
|
@ -22,17 +22,27 @@ window.getComputedStyle = function getComputedStyleStub (el) {
|
||||
|
||||
global.beforeEach(() => {
|
||||
window.process = {
|
||||
cwd: process.cwd,
|
||||
env: {
|
||||
NODE_ENV: 'development'
|
||||
},
|
||||
versions: {
|
||||
chromium: '77.0.3865.75',
|
||||
nw: '0.41.1',
|
||||
chromium: '84.0.4147.89',
|
||||
nw: '0.47.0',
|
||||
'nw-flavor': 'sdk',
|
||||
node: '12.9.1'
|
||||
node: '14.5.0'
|
||||
}
|
||||
};
|
||||
window.nw = {
|
||||
require: jest.fn((module) => {
|
||||
if (module === 'fs') {
|
||||
return {
|
||||
readdirSync: jest.fn(() => {
|
||||
return ['example-file-1.ext', 'example-file-2.ext'];
|
||||
})
|
||||
};
|
||||
}
|
||||
}),
|
||||
Shell: {
|
||||
openExternal: jest.fn()
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user