This commit is contained in:
Benjamin Bädorf 2020-05-19 13:45:14 +02:00
commit 76df0f29e9
No known key found for this signature in database
GPG key ID: 4406E80E13CD656C
28 changed files with 16897 additions and 0 deletions

3
.browserslistrc Normal file
View file

@ -0,0 +1,3 @@
> 1%
last 2 versions
not dead

7
.editorconfig Normal file
View file

@ -0,0 +1,7 @@
[*.{js,jsx,ts,tsx,vue}]
indent_style = space
indent_size = 2
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 100

29
.eslintrc.js Normal file
View file

@ -0,0 +1,29 @@
module.exports = {
root: true,
env: {
node: true,
},
extends: [
'plugin:vue/essential',
'@vue/airbnb',
'@vue/typescript/recommended',
],
parserOptions: {
ecmaVersion: 2020,
},
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
},
overrides: [
{
files: [
'**/__tests__/*.{j,t}s?(x)',
'**/tests/unit/**/*.spec.{j,t}s?(x)',
],
env: {
jest: true,
},
},
],
};

26
.gitignore vendored Normal file
View file

@ -0,0 +1,26 @@
.DS_Store
node_modules
/dist
/tests/e2e/reports/
selenium-debug.log
chromedriver.log
geckodriver.log
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

34
README.md Normal file
View file

@ -0,0 +1,34 @@
# schlechtenburg
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Run your unit tests
```
npm run test:unit
```
### Run your end-to-end tests
```
npm run test:e2e
```
### Lints and fixes files
```
npm run lint
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).

5
babel.config.js Normal file
View file

@ -0,0 +1,5 @@
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset',
],
};

3
jest.config.js Normal file
View file

@ -0,0 +1,3 @@
module.exports = {
preset: '@vue/cli-plugin-unit-jest/presets/typescript-and-babel',
};

16234
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

39
package.json Normal file
View file

@ -0,0 +1,39 @@
{
"name": "schlechtenburg",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"test:unit": "vue-cli-service test:unit",
"test:e2e": "vue-cli-service test:e2e",
"lint": "vue-cli-service lint"
},
"dependencies": {
"core-js": "^3.6.4",
"vue": "^2.6.11"
},
"devDependencies": {
"@types/jest": "^24.0.19",
"@typescript-eslint/eslint-plugin": "^2.26.0",
"@typescript-eslint/parser": "^2.26.0",
"@vue/cli-plugin-babel": "~4.3.0",
"@vue/cli-plugin-e2e-nightwatch": "~4.3.0",
"@vue/cli-plugin-eslint": "~4.3.0",
"@vue/cli-plugin-typescript": "~4.3.0",
"@vue/cli-plugin-unit-jest": "~4.3.0",
"@vue/cli-service": "~4.3.0",
"@vue/eslint-config-airbnb": "^5.0.2",
"@vue/eslint-config-typescript": "^5.0.2",
"@vue/test-utils": "1.0.0-beta.31",
"chromedriver": "^80.0.1",
"eslint": "^6.7.2",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-vue": "^6.2.2",
"geckodriver": "^1.19.1",
"sass": "^1.26.3",
"sass-loader": "^8.0.2",
"typescript": "~3.8.3",
"vue-template-compiler": "^2.6.11"
}
}

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

17
public/index.html Normal file
View file

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

29
src/App.vue Normal file
View file

@ -0,0 +1,29 @@
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js + TypeScript App"/>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import HelloWorld from './components/HelloWorld.vue';
export default Vue.extend({
name: 'App',
components: {
HelloWorld,
},
});
</script>
<style lang="scss">
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>

BIN
src/assets/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

View file

@ -0,0 +1,63 @@
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<p>
For a guide and recipes on how to configure / customize this project,<br>
check out the
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
</p>
<h3>Installed CLI Plugins</h3>
<ul>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-typescript" target="_blank" rel="noopener">typescript</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-unit-jest" target="_blank" rel="noopener">unit-jest</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-e2e-nightwatch" target="_blank" rel="noopener">e2e-nightwatch</a></li>
</ul>
<h3>Essential Links</h3>
<ul>
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
</ul>
<h3>Ecosystem</h3>
<ul>
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
</ul>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
name: 'HelloWorld',
props: {
msg: String,
},
});
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>

8
src/main.ts Normal file
View file

@ -0,0 +1,8 @@
import Vue from 'vue';
import App from './App.vue';
Vue.config.productionTip = false;
new Vue({
render: (h) => h(App),
}).$mount('#app');

13
src/shims-tsx.d.ts vendored Normal file
View file

@ -0,0 +1,13 @@
import Vue, { VNode } from 'vue';
declare global {
namespace JSX {
// tslint:disable no-empty-interface
interface Element extends VNode {}
// tslint:disable no-empty-interface
interface ElementClass extends Vue {}
interface IntrinsicElements {
[elem: string]: any;
}
}
}

5
src/shims-vue.d.ts vendored Normal file
View file

@ -0,0 +1,5 @@
declare module '*.vue' {
import Vue from 'vue';
export default Vue;
}

6
tests/e2e/.eslintrc.js Normal file
View file

@ -0,0 +1,6 @@
module.exports = {
rules: {
'@typescript-eslint/no-var-requires': 'off',
'no-unused-expressions': 'off',
},
};

View file

@ -0,0 +1,34 @@
/**
* A custom Nightwatch assertion. The assertion name is the filename.
*
* Example usage:
* browser.assert.elementCount(selector, count)
*
* For more information on custom assertions see:
* https://nightwatchjs.org/guide/extending-nightwatch/#writing-custom-assertions
*
*
* @param {string|object} selectorOrObject
* @param {number} count
*/
exports.assertion = function elementCount(selectorOrObject, count) {
let selector;
// when called from a page object element or section
if (typeof selectorOrObject === 'object' && selectorOrObject.selector) {
// eslint-disable-next-line prefer-destructuring
selector = selectorOrObject.selector;
} else {
selector = selectorOrObject;
}
this.message = `Testing if element <${selector}> has count: ${count}`;
this.expected = count;
this.pass = (val) => val === count;
this.value = (res) => res.value;
function evaluator(_selector) {
return document.querySelectorAll(_selector).length;
}
this.command = (cb) => this.api.execute(evaluator, [selector], cb);
};

View file

@ -0,0 +1,37 @@
/**
* A very basic Nightwatch custom command. The command name is the filename and the
* exported "command" function is the command.
*
* Example usage:
* browser.customExecute(function() {
* console.log('Hello from the browser window')
* });
*
* For more information on writing custom commands see:
* https://nightwatchjs.org/guide/extending-nightwatch/#writing-custom-commands
*
* @param {*} data
*/
exports.command = function command(data) {
// Other Nightwatch commands are available via "this"
// .execute() inject a snippet of JavaScript into the page for execution.
// the executed script is assumed to be synchronous.
//
// See https://nightwatchjs.org/api/execute.html for more info.
//
this.execute(
// The function argument is converted to a string and sent to the browser
(argData) => argData,
// The arguments for the function to be sent to the browser are specified in this array
[data],
(result) => {
// The "result" object contains the result of what we have sent back from the browser window
console.log('custom execute result:', result.value);
},
);
return this;
};

View file

@ -0,0 +1,23 @@
/**
* A basic Nightwatch custom command
* which demonstrates usage of ES6 async/await instead of using callbacks.
* The command name is the filename and the exported "command" function is the command.
*
* Example usage:
* browser.openHomepage();
*
* For more information on writing custom commands see:
* https://nightwatchjs.org/guide/extending-nightwatch/#writing-custom-commands
*
*/
module.exports = {
async command() {
// Other Nightwatch commands are available via "this"
// .init() simply calls .url() command with the value of the "launch_url" setting
this.init();
this.waitForElementVisible('#app');
const result = await this.elements('css selector', '#app ul');
this.assert.strictEqual(result.value.length, 3);
},
};

View file

@ -0,0 +1,24 @@
/**
* A class-based Nightwatch custom command which is a variation of the openHomepage.js command.
* The command name is the filename and class needs to contain a "command" method.
*
* Example usage:
* browser.openHomepageClass();
*
* For more information on writing custom commands see:
* https://nightwatchjs.org/guide/extending-nightwatch/#writing-custom-commands
*
*/
const assert = require('assert');
module.exports = class {
async command() {
// Other Nightwatch commands are available via "this.api"
this.api.init();
this.api.waitForElementVisible('#app');
const result = await this.api.elements('css selector', '#app ul');
assert.strictEqual(result.value.length, 3);
}
};

104
tests/e2e/globals.js Normal file
View file

@ -0,0 +1,104 @@
// /////////////////////////////////////////////////////////////////////////////////
// Refer to the entire list of global config settings here:
// https://github.com/nightwatchjs/nightwatch/blob/master/lib/settings/defaults.js#L16
//
// More info on test globals:
// https://nightwatchjs.org/gettingstarted/configuration/#test-globals
//
// /////////////////////////////////////////////////////////////////////////////////
module.exports = {
// this controls whether to abort the test execution when an assertion failed and skip the rest
// it's being used in waitFor commands and expect assertions
abortOnAssertionFailure: true,
// this will overwrite the default polling interval (currently 500ms) for waitFor commands
// and expect assertions that use retry
waitForConditionPollInterval: 500,
// default timeout value in milliseconds for waitFor commands and implicit waitFor value for
// expect assertions
waitForConditionTimeout: 5000,
default: {
/*
The globals defined here are available everywhere in any test env
*/
/*
myGlobal: function() {
return 'I\'m a method';
}
*/
},
firefox: {
/*
The globals defined here are available only when the chrome testing env is being used
i.e. when running with --env firefox
*/
/*
* myGlobal: function() {
* return 'Firefox specific global';
* }
*/
},
// ///////////////////////////////////////////////////////////////
// Global hooks
// - simple functions which are executed as part of the test run
// - take a callback argument which can be called when an async
// async operation is finished
// ///////////////////////////////////////////////////////////////
/**
* executed before the test run has started, so before a session is created
*/
/*
before(cb) {
//console.log('global before')
cb();
},
*/
/**
* executed before every test suite has started
*/
/*
beforeEach(browser, cb) {
//console.log('global beforeEach')
cb();
},
*/
/**
* executed after every test suite has ended
*/
/*
afterEach(browser, cb) {
browser.perform(function() {
//console.log('global afterEach')
cb();
});
},
*/
/**
* executed after the test run has finished
*/
/*
after(cb) {
//console.log('global after')
cb();
},
*/
// ///////////////////////////////////////////////////////////////
// Global reporter
// - define your own custom reporter
// ///////////////////////////////////////////////////////////////
/*
reporter(results, cb) {
cb();
}
*/
};

View file

@ -0,0 +1,52 @@
/**
* A Nightwatch page object. The page object name is the filename.
*
* Example usage:
* browser.page.homepage.navigate()
*
* For more information on working with page objects see:
* https://nightwatchjs.org/guide/working-with-page-objects/
*
*/
module.exports = {
url: '/',
commands: [],
// A page object can have elements
elements: {
appContainer: '#app',
},
// Or a page objects can also have sections
sections: {
app: {
selector: '#app',
elements: {
logo: 'img',
},
// - a page object section can also have sub-sections
// - elements or sub-sections located here are retrieved using the "app" section as the base
sections: {
headline: {
selector: 'h1',
},
welcome: {
// the equivalent css selector for the "welcome" sub-section would be:
// '#app div.hello'
selector: 'div.hello',
elements: {
cliPluginLinks: {
selector: 'ul',
index: 0,
},
},
},
},
},
},
};

View file

@ -0,0 +1,30 @@
// //////////////////////////////////////////////////////////////
// For authoring Nightwatch tests, see
// https://nightwatchjs.org/guide
//
// For more information on working with page objects see:
// https://nightwatchjs.org/guide/working-with-page-objects/
// //////////////////////////////////////////////////////////////
module.exports = {
beforeEach: (browser) => browser.init(),
'e2e tests using page objects': (browser) => {
const homepage = browser.page.homepage();
homepage.waitForElementVisible('@appContainer');
const { app } = homepage.section;
app.assert.elementCount('@logo', 1);
app.expect.section('@welcome').to.be.visible;
app.expect.section('@headline').text.to.match(/^Welcome to Your Vue\.js (.*)App$/);
browser.end();
},
'verify if string "e2e-nightwatch" is within the cli plugin links': (browser) => {
const homepage = browser.page.homepage();
const welcomeSection = homepage.section.app.section.welcome;
welcomeSection.expect.element('@cliPluginLinks').text.to.contain('e2e-nightwatch');
},
};

21
tests/e2e/specs/test.js Normal file
View file

@ -0,0 +1,21 @@
// For authoring Nightwatch tests, see
// https://nightwatchjs.org/guide
module.exports = {
'default e2e tests': (browser) => {
browser
.init()
.waitForElementVisible('#app')
.assert.elementPresent('.hello')
.assert.containsText('h1', 'Welcome to Your Vue.js + TypeScript App')
.assert.elementCount('img', 1)
.end();
},
'example e2e test using a custom command': (browser) => {
browser
.openHomepage()
.assert.elementPresent('.hello')
.end();
},
};

View file

@ -0,0 +1,12 @@
import { shallowMount } from '@vue/test-utils';
import HelloWorld from '@/components/HelloWorld.vue';
describe('HelloWorld.vue', () => {
it('renders props.msg when passed', () => {
const msg = 'new message';
const wrapper = shallowMount(HelloWorld, {
propsData: { msg },
});
expect(wrapper.text()).toMatch(msg);
});
});

39
tsconfig.json Normal file
View file

@ -0,0 +1,39 @@
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"strict": true,
"jsx": "preserve",
"importHelpers": true,
"moduleResolution": "node",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"baseUrl": ".",
"types": [
"webpack-env",
"jest"
],
"paths": {
"@/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
},
"include": [
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue",
"tests/**/*.ts",
"tests/**/*.tsx"
],
"exclude": [
"node_modules"
]
}