Lerna + vue 3

vue3
Benjamin Bädorf 2020-12-27 22:32:43 +01:00
parent 28105f5315
commit 33585ee1a1
No known key found for this signature in database
GPG Key ID: 4406E80E13CD656C
87 changed files with 10421 additions and 16943 deletions

View File

@ -1,30 +0,0 @@
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',
'@typescript-eslint/no-empty-function': 0,
},
overrides: [
{
files: [
'**/__tests__/*.{j,t}s?(x)',
'**/tests/unit/**/*.spec.{j,t}s?(x)',
],
env: {
jest: true,
},
},
],
};

29
.gitignore vendored
View File

@ -1,26 +1,5 @@
.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?
.DS_Store
dist
dist-ssr
*.local

View File

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

View File

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

6
lerna.json Normal file
View File

@ -0,0 +1,6 @@
{
"packages": [
"packages/*"
],
"version": "0.0.0"
}

16276
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,47 +1,4 @@
{
"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": {
"@vue/composition-api": "^0.5.0",
"core-js": "^3.6.4",
"lodash-es": "^4.17.15",
"vue": "^2.6.11"
},
"devDependencies": {
"@types/jest": "^24.0.19",
"@types/lodash-es": "^4.17.3",
"@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",
"babel-preset-vca-jsx": "^0.3.5",
"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.9.3",
"vue-template-compiler": "^2.6.11",
"vuex": "^3.4.0"
},
"peerDependencies": {
"vuex": "^3.4.0"
}
"version": "0.0.0"
}

11
packages/core/README.md Normal file
View File

@ -0,0 +1,11 @@
# `@schlechtenburg/core`
> TODO: description
## Usage
```
const core = require('@schlechtenburg/core');
// TODO: DEMONSTRATE API
```

View File

@ -0,0 +1,7 @@
'use strict';
const core = require('..');
describe('@schlechtenburg/core', () => {
it('needs tests');
});

13
packages/core/index.html Normal file
View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vite App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/lib/main.ts"></script>
</body>
</html>

View File

@ -1,10 +1,6 @@
import {
defineComponent,
reactive,
ref,
} from '@vue/composition-api';
import Schlechtenburg from '@components/Schlechtenburg';
import { Block } from './components/TreeElement';
import { defineComponent, reactive, ref } from 'vue';
import Schlechtenburg from '/@components/Schlechtenburg';
import { Block, SbMode } from '/@components/TreeElement';
import initialData from './initial-data.json';
@ -21,20 +17,15 @@ export default defineComponent({
<div id="app">
<select
value={activeTab.value}
{...{
on: {
change: ($event: Event) => {
activeTab.value = ($event.target as HTMLSelectElement).value;
},
},
}}
onchange={($event: Event) => { activeTab.value = ($event.target as HTMLSelectElement).value; }}
>
<option>edit</option>
<option>display</option>
<option>json</option>
</select>
<Schlechtenburg
vShow={activeTab.value === 'edit'}
v-show={activeTab.value === 'edit'}
block={block}
eventUpdate={(newBlock: Block) => {
block.name = newBlock.name;
@ -44,12 +35,12 @@ export default defineComponent({
/>
<Schlechtenburg
vShow={activeTab.value === 'display'}
v-show={activeTab.value === 'display'}
block={block}
mode="display"
mode={SbMode.Display}
/>
<pre vShow={activeTab.value === 'json'}>
<pre v-show={activeTab.value === 'json'}>
<code>{JSON.stringify(block, null, 2)}</code>
</pre>
</div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@ -1,12 +1,11 @@
import {
defineComponent,
provide,
reactive,
shallowReactive,
ref,
PropType,
Ref,
watch,
} from '@vue/composition-api';
} from 'vue';
import {
model,
ActiveBlock,
@ -18,14 +17,14 @@ import {
BlockLibraryDefinition,
BlockLibrary,
useResizeObserver,
} from '@components/TreeElement';
} from '/@components/TreeElement';
import SbBlock from '@internal/Block';
import SbBlock from '/@internal/Block';
import SbLayout from '@user/Layout/index';
import SbParagraph from '@user/Paragraph/index';
import SbImage from '@user/Image/index';
import SbHeading from '@user/Heading/index';
import SbLayout from '/@user/Layout/index';
import SbParagraph from '/@user/Paragraph/index';
import SbImage from '/@user/Image/index';
import SbHeading from '/@user/Heading/index';
import './Schlechtenburg.scss';
@ -46,11 +45,11 @@ export default defineComponent({
block: { type: Object as PropType<Block>, required: true },
eventUpdate: { type: Function, default: () => {} },
mode: {
type: String,
type: String as SbMode,
validator(value: string) {
return ['edit', 'display'].includes(value);
return Object.values(SbMode).includes(value);
},
default: 'edit',
default: SbMode.Edit,
},
},
@ -64,7 +63,7 @@ export default defineComponent({
const activeBlock = ref(null);
provide(ActiveBlock, activeBlock);
const blockLibrary: BlockLibraryDefinition = reactive({
const blockLibrary: BlockLibraryDefinition = shallowReactive({
'sb-layout': SbLayout,
'sb-image': SbImage,
'sb-paragraph': SbParagraph,
@ -77,6 +76,7 @@ export default defineComponent({
{},
),
});
provide(BlockLibrary, blockLibrary);
return () => (

View File

@ -6,7 +6,7 @@ import {
computed,
watch,
provide,
} from '@vue/composition-api';
} from 'vue';
export interface BlockDefinition {
name: string;

View File

@ -1,11 +1,11 @@
import {
computed,
defineComponent,
computed,
watch,
PropType,
ref,
Ref,
} from '@vue/composition-api';
} from 'vue';
import {
Block,
useDynamicBlocks,
@ -13,7 +13,7 @@ import {
SbMode,
BlockDimensions,
useResizeObserver,
} from '@components/TreeElement';
} from '/@components/TreeElement';
import SbBlockOrdering from './BlockOrdering';
@ -60,6 +60,7 @@ export default defineComponent({
}));
const BlockComponent = getBlock(props.block.name) as any;
if (mode.value === SbMode.Display) {
return () => (
<BlockComponent

View File

@ -1,19 +1,19 @@
import debounce from 'lodash-es/debounce';
import {
defineComponent,
watch,
reactive,
computed,
} from '@vue/composition-api';
defineAsyncComponent,
} from 'vue';
import {
useBlockSizing,
} from '@components/TreeElement';
} from '/@components/TreeElement';
import SbButton from './Button';
import './BlockOrdering.scss';
export default defineComponent({
export default defineAsyncComponent({
name: 'sb-block-ordering',
props: {

View File

@ -1,8 +1,8 @@
import {
computed,
defineComponent,
ref,
} from '@vue/composition-api';
defineComponent,
} from 'vue';
import {
useDynamicBlocks,
BlockDefinition,

View File

@ -1,4 +1,4 @@
import { defineComponent } from '@vue/composition-api';
import { defineComponent } from 'vue';
import { BlockDefinition } from '../TreeElement';
import BlockPicker from './BlockPicker';

View File

@ -1,5 +1,4 @@
import { defineComponent } from '@vue/composition-api';
import { defineComponent } from 'vue';
import './Button.scss';
export default defineComponent({

View File

@ -1,7 +1,7 @@
import {
defineComponent,
computed,
} from '@vue/composition-api';
} from 'vue';
import './Modal.scss';

View File

@ -1,5 +1,4 @@
import { defineComponent } from '@vue/composition-api';
import { defineComponent } from 'vue';
import './Select.scss';
export default defineComponent({

View File

@ -3,8 +3,8 @@ import {
defineComponent,
watch,
reactive,
} from '@vue/composition-api';
import { useBlockSizing } from '@components/TreeElement';
} from 'vue';
import { useBlockSizing } from '/@components/TreeElement';
import './Toolbar.scss';

View File

@ -0,0 +1,9 @@
import { defineAsyncComponent } from 'vue';
import { getDefaultData } from './util';
export default {
name: 'sb-heading',
getDefaultData,
edit: defineAsyncComponent(() => import('./edit')),
display: defineAsyncComponent(() => import('./edit')),
};

View File

@ -1,8 +1,8 @@
import { defineComponent, PropType } from '@vue/composition-api';
import { defineAsyncComponent, PropType } from 'vue';
import {
model,
blockProps,
} from '@components/TreeElement';
} from '/@components/TreeElement';
import {
getDefaultData,
@ -12,7 +12,7 @@ import {
import './style.scss';
export default defineComponent({
export default defineAsyncComponent({
name: 'sb-image-display',
model,
@ -26,6 +26,8 @@ export default defineComponent({
},
setup(props: ImageProps) {
console.log('img display', props.data);
return () => <img
class="sb-image"
src={props.data.src}

View File

@ -1,18 +1,18 @@
import {
defineComponent,
defineAsyncComponent,
reactive,
ref,
Ref,
watch,
PropType,
} from '@vue/composition-api';
} from 'vue';
import {
model,
blockProps,
} from '@components/TreeElement';
} from '/@components/TreeElement';
import SbToolbar from '@internal/Toolbar';
import SbButton from '@internal/Button';
import SbToolbar from '/@internal/Toolbar';
import SbButton from '/@internal/Button';
import {
getDefaultData,
@ -22,7 +22,7 @@ import {
import './style.scss';
export default defineComponent({
export default defineAsyncComponent({
name: 'sb-image-edit',
model,

View File

@ -0,0 +1,9 @@
import { defineAsyncComponent } from 'vue';
import { getDefaultData } from './util';
export default {
name: 'sb-image',
getDefaultData,
edit: defineAsyncComponent(() => import('./edit')),
display: defineAsyncComponent(() => import('./display')),
};

View File

@ -1,4 +1,4 @@
import { BlockData, BlockProps } from '@components/TreeElement';
import { BlockData, BlockProps } from '/@components/TreeElement';
export interface ImageData {
src: string;

View File

@ -1,14 +1,14 @@
import {
computed,
defineComponent,
computed,
PropType,
} from '@vue/composition-api';
} from 'vue';
import {
model,
blockProps,
} from '@components/TreeElement';
} from '/@components/TreeElement';
import SbBlock from '@internal/Block';
import SbBlock from '/@internal/Block';
import {
LayoutData,
@ -37,6 +37,8 @@ export default defineComponent({
[`sb-layout_${props.data.orientation}`]: true,
}));
console.log('layout display', props.data);
return () => (
<div class={classes.value}>
{...props.data.children.map((child) => (

View File

@ -1,21 +1,21 @@
import {
defineComponent,
reactive,
computed,
defineComponent,
watch,
PropType,
} from '@vue/composition-api';
} from 'vue';
import {
model,
useActivation,
Block,
blockProps,
} from '@components/TreeElement';
} from '/@components/TreeElement';
import SbBlock from '@internal/Block';
import SbButton from '@internal/Button';
import SbToolbar from '@internal/Toolbar';
import SbBlockPlaceholder from '@internal/BlockPlaceholder';
import SbBlock from '/@internal/Block';
import SbButton from '/@internal/Button';
import SbToolbar from '/@internal/Toolbar';
import SbBlockPlaceholder from '/@internal/BlockPlaceholder';
import {
LayoutData,
@ -144,6 +144,8 @@ export default defineComponent({
props.eventUpdate({ children: [...localData.children] });
};
console.log('Rendering edit');
return () => (
<div class={classes.value}>
<SbToolbar slot="toolbar">

View File

@ -0,0 +1,9 @@
import { defineAsyncComponent } from 'vue';
import { getDefaultData } from './util';
export default {
name: 'sb-layout',
getDefaultData,
edit: defineAsyncComponent(() => import('./edit')),
display: defineAsyncComponent(() => import('./display')),
};

View File

@ -2,7 +2,7 @@ import {
BlockProps,
Block,
BlockData,
} from '@components/TreeElement';
} from '/@components/TreeElement';
export interface LayoutData {
orientation: string;

View File

@ -1,13 +1,13 @@
import {
defineComponent,
defineAsyncComponent,
computed,
PropType,
} from '@vue/composition-api';
} from 'vue';
import {
model,
blockProps,
BlockProps,
} from '@components/TreeElement';
} from '/@components/TreeElement';
import {
getDefaultData,
@ -20,7 +20,7 @@ interface ParagraphProps extends BlockProps {
data: ParagraphData;
}
export default defineComponent({
export default defineAsyncComponent({
name: 'sb-paragraph-display',
model,
@ -39,6 +39,8 @@ export default defineComponent({
[`sb-paragraph_align-${props.data.align}`]: true,
}));
console.log('p display', props.data);
return () => <p
class={classes.value}
{...{

View File

@ -1,5 +1,5 @@
import {
defineComponent,
defineAsyncComponent,
reactive,
computed,
ref,
@ -7,17 +7,17 @@ import {
onMounted,
watch,
PropType,
} from '@vue/composition-api';
} from 'vue';
import {
model,
blockProps,
BlockProps,
BlockData,
useActivation,
} from '@components/TreeElement';
} from '/@components/TreeElement';
import SbToolbar from '@internal/Toolbar';
import SbSelect from '@internal/Select';
import SbToolbar from '/@internal/Toolbar';
import SbSelect from '/@internal/Select';
import {
getDefaultData,
@ -33,7 +33,7 @@ interface ParagraphProps extends BlockProps {
eventRemoveBlock: () => void;
}
export default defineComponent({
export default defineAsyncComponent({
name: 'sb-paragraph-edit',
model,
@ -163,4 +163,4 @@ export default defineComponent({
</div>
);
},
});
};

View File

@ -0,0 +1,9 @@
import { defineAsyncComponent } from 'vue';
import { getDefaultData } from './util';
export default {
name: 'sb-paragraph',
getDefaultData,
edit: defineAsyncComponent(() => import('./edit')),
display: defineAsyncComponent(() => import('./display')),
};

View File

@ -0,0 +1,5 @@
import { createApp } from 'vue'
import App from './App';
import './main.scss';
createApp(App).mount('#app');

1
packages/core/lib/shims-tsx.d.ts vendored Normal file
View File

@ -0,0 +1 @@
// file: shim-tsx.d.ts

10054
packages/core/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,38 @@
{
"name": "@schlechtenburg/core",
"version": "0.0.0",
"description": "> TODO: description",
"author": "Benjamin Bädorf <hello@benjaminbaedorf.eu>",
"homepage": "",
"license": "GPLv3",
"main": "lib/core.js",
"directories": {
"lib": "lib",
"test": "__tests__"
},
"files": [
"lib"
],
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "git@git.b12f.io:b12f/schlechtenburg.git"
},
"scripts": {
"dev": "vite",
"build": "vuedx-typecheck . && vite build"
},
"dependencies": {
"vue": "^3.0.4"
},
"devDependencies": {
"@vue/compiler-sfc": "^3.0.4",
"@vuedx/typecheck": "^0.3.1-insiders-1606311019.0",
"@vuedx/typescript-plugin-vue": "^0.3.1-insiders-1606311019.0",
"lerna": "^3.22.1",
"typescript": "^4.1.2",
"vite": "^1.0.0-rc.13"
}
}

View File

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -0,0 +1,13 @@
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"jsx": "preserve",
"sourceMap": true,
"lib": ["esnext", "dom"],
"plugins": [{ "name": "@vuedx/typescript-plugin-vue" }]
},
"include": ["lib/**/*.ts", "lib/**/*.d.ts", "lib/**/*.tsx", "lib/**/*.vue"]
}

View File

@ -0,0 +1,13 @@
const path = require('path');
const ROOT_DIR = path.resolve(__dirname);
const SRC_DIR = path.resolve(ROOT_DIR, 'lib');
module.exports = {
alias: {
'/@/': SRC_DIR,
'/@components/': path.join(SRC_DIR, 'components'),
'/@internal/': path.join(SRC_DIR, 'components/internal'),
'/@user/': path.join(SRC_DIR, 'components/user'),
},
};

View File

@ -1,17 +0,0 @@
<!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>

16
src/App.vue Normal file
View File

@ -0,0 +1,16 @@
<template>
<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld msg="Hello Vue 3.0 + Vite" />
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import HelloWorld from './components/HelloWorld.vue'
export default defineComponent({
name: 'App',
components: {
HelloWorld
}
})
</script>

View File

@ -0,0 +1,47 @@
<template>
<h1>{{ msg }}</h1>
<p>
Recommended setup:
<a href="https://code.visualstudio.com/" target="_blank">VSCode</a>
+
<a
href="https://marketplace.visualstudio.com/items?itemName=octref.vetur"
target="_blank"
>Vetur</a
>
+
<a
href="https://marketplace.visualstudio.com/items?itemName=znck.vue-language-features-insiders"
target="_blank"
>Vue Language Features (Insiders)</a
>
</p>
<p>
Make sure to use workspace version of TypeScript to get improved support via
<a href="https://github.com/znck/vue-developer-experience" target="_blank"
>@vuedx</a
>. Note @vuedx is still experimental and this setup is provided for early feedback.
</p>
<button @click="count++">count is: {{ count }}</button>
<p>
Edit <code>components/HelloWorld.vue</code> to test hot module replacement.
</p>
</template>
<script lang="ts">
import { ref, defineComponent } from 'vue'
export default defineComponent({
name: 'HelloWorld',
props: {
msg: {
type: String,
required: true
}
},
setup: () => {
const count = ref(0)
return { count }
}
})
</script>

View File

@ -1,8 +0,0 @@
import { getDefaultData } from './util';
export default {
name: 'sb-heading',
getDefaultData,
edit: () => import('./edit'),
display: () => import('./edit'),
};

View File

@ -1,8 +0,0 @@
import { getDefaultData } from './util';
export default {
name: 'sb-image',
getDefaultData,
edit: () => import('./edit'),
display: () => import('./display'),
};

View File

@ -1,8 +0,0 @@
import { getDefaultData } from './util';
export default {
name: 'sb-layout',
getDefaultData,
edit: () => import('./edit'),
display: () => import('./display'),
};

View File

@ -1,8 +0,0 @@
import { getDefaultData } from './util';
export default {
name: 'sb-paragraph',
getDefaultData,
edit: () => import('./edit'),
display: () => import('./display'),
};

8
src/index.css Normal file
View File

@ -0,0 +1,8 @@
#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;
}

View File

@ -1,13 +1,5 @@
import Vue from 'vue';
import VueCompositionApi from '@vue/composition-api';
import App from './App';
import { createApp } from 'vue'
import App from './App.vue'
import './index.css'
import './main.scss';
Vue.config.productionTip = false;
Vue.use(VueCompositionApi);
new Vue({
render: (h) => h(App),
}).$mount('#app');
createApp(App).mount('#app')

18
src/shims-tsx.d.ts vendored
View File

@ -1,18 +0,0 @@
// file: shim-tsx.d.ts
import Vue, { VNode } from 'vue';
import { ComponentRenderProxy } from '@vue/composition-api';
declare global {
namespace JSX {
// tslint:disable no-empty-interface
interface Element extends VNode {}
// tslint:disable no-empty-interface
interface ElementClass extends ComponentRenderProxy {}
interface ElementAttributesProperty {
$props: any; // specify the property name to use
}
interface IntrinsicElements {
[elem: string]: any;
}
}
}

64
src/vue-app-env.d.ts vendored Normal file
View File

@ -0,0 +1,64 @@
declare namespace NodeJS {
interface Process{
env: ProcessEnv
}
interface ProcessEnv {
/**
* By default, there are two modes in Vite:
*
* * `development` is used by vite and vite serve
* * `production` is used by vite build
*
* You can overwrite the default mode used for a command by passing the --mode option flag.
*
*/
readonly NODE_ENV: 'development' | 'production'
}
}
declare var process: NodeJS.Process
declare module '*.gif' {
const src: string
export default src
}
declare module '*.jpg' {
const src: string
export default src
}
declare module '*.jpeg' {
const src: string
export default src
}
declare module '*.png' {
const src: string
export default src
}
declare module '*.webp' {
const src: string
export default src
}
declare module '*.svg' {
const src: string;
export default src
}
declare module '*.module.css' {
const classes: { readonly [key: string]: string }
export default classes
}
declare module '*.module.scss' {
const classes: { readonly [key: string]: string }
export default classes
}
declare module '*.module.sass' {
const classes: { readonly [key: string]: string }
export default classes
}

View File

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

View File

@ -1,34 +0,0 @@
/**
* 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

@ -1,37 +0,0 @@
/**
* 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

@ -1,23 +0,0 @@
/**
* 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

@ -1,24 +0,0 @@
/**
* 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);
}
};

View File

@ -1,104 +0,0 @@
// /////////////////////////////////////////////////////////////////////////////////
// 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

@ -1,52 +0,0 @@
/**
* 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

@ -1,30 +0,0 @@
// //////////////////////////////////////////////////////////////
// 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');
},
};

View File

@ -1,21 +0,0 @@
// 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

@ -1,12 +0,0 @@
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);
});
});

View File

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

View File

@ -1,14 +0,0 @@
const path = require('path');
const ROOT_DIR = path.resolve(__dirname);
const SRC_DIR = path.resolve(ROOT_DIR, 'src');
module.exports = {
chainWebpack(config) {
config.resolve.alias
.set('@', SRC_DIR)
.set('@components', path.join(SRC_DIR, 'components'))
.set('@internal', path.join(SRC_DIR, 'components/internal'))
.set('@user', path.join(SRC_DIR, 'components/user'));
},
};