文章分为三部分讲解,项目采用vue-cli + vue/cli-plugin-e2e-cypress配合讲解javascript
npm install -g @vue/cli // 能够用yarn 习惯npm了
vue create hello-world // 建立本身喜欢的工程吧 最近楼主不推荐配置eslint 本身配置eslint + Prettier吧 standard标准不支持Prettier 😭
复制代码
"start": "vue-cli-service serve", // 开发 + 测试环境
"serve": "vue-cli-service serve --mode test", // 联调 + 后端小姐姐
"dev": "vue-cli-service build --mode dev", // 测试环境部署
"build": "vue-cli-service build", // 线上环境部署
复制代码
// 不一样环境配置
touch .env.test
echo NODE_ENV = 'development' > .env.test
// webpack alias + webstorm配置(实在不想写../../这种)
touch vue.config.js
const path = require('path')
module.exports = {
configureWebpack: {
plugins: []
},
chainWebpack: config => {
config.resolve.alias
.set('@', path.join(__dirname, 'src'))
.set('component', path.join(__dirname, 'src', 'components'))
.set('config', path.join(__dirname, 'src', 'config'))
// webstorm配置
commond + ,
输出webpack
自定义配置文件 node_modules/@vue-cli/server/webpack.config.js + apply
尽情的command + B 🎇🎇🎇🎇🎇🎇
// 不喜欢用lodash get方法 以为写起来很差看 又不是typescript 幸亏有Babel爸爸
npm i '@babel/plugin-proposal-optional-chaining' -D
touch .babelrc
module.exports = {
'presets': [
'@vue/app'
],
'plugins': [
'@babel/plugin-proposal-optional-chaining'
]
}
const a = { c: 1 }
console.log(a?.b) // 不会中断程序执行 是否是写起来很舒服
复制代码
import Vue from 'vue'
import Loading from './Loading' // Loading 怎么实现 自由发挥
let instance
let ZIndex = 101
const LoadingBuilder = function (type) {
return (options) => {
if (Vue.prototype.$isServer) return false
options = options || {}
let data = Object.assign({}, options, { type: type, ZIndex: ZIndex })
instance = new Loading({
data: data
})
instance.vm = instance.$mount()
document.body.appendChild(instance.vm.$el)
instance.dom = instance.vm.$el
instance.vm.open()
ZIndex = ZIndex + 1
return instance.vm
}
}
const LoadingComponent = {}
LoadingComponent.install = function (Vue, opts = {}) {
const Loading = LoadingBuilder()
Vue.$loading = Loading
window.$loading = Loading
Object.defineProperties(Vue.prototype, {
loading: {
get () {
return Loading
}
},
$loading: {
get () {
return Loading
}
}
})
}
export default LoadingComponent
复制代码
vue add @vue/e2e-cypress
复制代码
目录介绍html
如下是自动生成的vue
├── tests
│ └── e2e
│ ├── plugins // 配置测试文件保存的地方
│ │ └── index.js
│ ├── specs // 写测试的地方
│ │ └── test.js
│ └── support // 写自定义命令的地方
│ ├── commands.js
│ └── index.js
复制代码
"test": "vue-cli-service test:e2e --mode dev", // 本地开发用
"test:e2e": "vue-cli-service test:e2e --headless --mode dev", // 跑Jenkins用的
复制代码
基本语法(官网确定讲的比我清楚,我这个快速入门)java
expect([]).to.be.a('Array') // 判断类型
expect(a.b).to.exist // 判断属性是否存在
expect(1).to.be.oneOf([1,2,3]) // 判断值是不是其中之一
expect('testing').to.match(/^test/) // 正则匹配
...
复制代码
describe('Test Login', () => {
before(() ={}) // 开始钩子
beforEach(() => {}) // 每一个测试开始前的钩子
it('login', () => {
cy.visit('/') // 访问根目录 cy.visit('http://localhost:3000')
cy.url().should('include', '/login') // 断言url 里面包含login
cy.get('.user-input')
.type('Jack z')
.should('have.value', 'Jack z') // 找到input.user-input 并输入Jack z 断言输入的值是Jack z
cy.get('.submit-button').click() // 获取.submit-button dom 并触发click事件
cy.get('#navbar').contains('关于').should('have.class', 'is-active') // 获取id为navbar文本内容是关于且有class是is-active
cy.wait(1000) // 等待1s
cy.pause() // 暂停
cy.server({method: '', header: {token: ''}, ...}) + cy.router('method', 'url', 'config') // 这个网络请求不能debugger
cy.request(method, url, config).then(() => {}) // 这个能够debugger
cy.contains().find().eq().each() // 跟JQuery同样 找DOM作出UI的判断
... // 支持动画测试(没用过 明试试 再补充)
})
after(() => {})
afterEach(() => {})
}
...
复制代码
// 自定义 setLocalStorage
Cypress.Commands.add('setLocalStorage', (key, value) => { window.localStorage.setItem(key, value)
cy.setLocalStorage('a', JSON.strigify('Jack z'))
复制代码
// 项目根目录 touch Jenkinsfile
pipeline {
agent {
docker {
image 'cypress/base:10' // 这个镜像包含了cypress运行的环境 推荐(否则你懂得 主要还得运维配合)
args '-u root:root' // 权限配置 否则npm install fail~~~~
}
}
environment {
CHROME_BIN = '/bin/google-chrome' // 全局配置环境变量
}
// Jenkins流水线下的配合
stages {
stage('下载依赖') { // 第一步pipe
steps {
sh 'rm -rf node_modules'
sh 'npm install'
sh 'npm rebuild node-sass'
}
}
stage('运行测试') { 第二步pipe
steps {
sh 'npm run test:e2e'
}
}
}
post {
always {
junit 'results/cypress-report.xml' // CI不经过的错误信息配置文件
// 钉钉通知 完美通知待更新
script {
def msg = "【${author}】你把服务器搞挂了,老詹喊你回家改BUG!"
def imageUrl = "https://www.iconsdb.com/icons/preview/red/x-mark-3-xxl.png"
if (currentBuild.currentResult=="SUCCESS"){
imageUrl= "http://icons.iconarchive.com/icons/paomedia/small-n-flat/1024/sign-check-icon.png"
msg ="【${author}】发布成功,干得不错!"
}
dingTalk accessToken:"xxxx",message:"${msg}",imageUrl:"${imageUrl}",messageUrl:"${BUILD_URL}"
}
}
}
}
复制代码
建立docker Jenkinsnode
docker run --name devops-jenkins --user=root -p 8080:8080 -p 50000:50000 -v /opt/data/jenkins_home:/var/jenkins_home -d jenkins/jenkins:lts
docker run --name devops-registry -p 5000:5000 -v /opt/devdata/registry:/var/lib/registry -d registry
启动完jenkins后经过浏览器输入地址http://部署jenkins主机IP:端口
以后主页面上有怎么查看登陆的密码
以后选择通用配置
进来以后 开始上图
复制代码
输入完管理员帐号后,点击continue as admin 进入管理界面点击系统管理-插件管理中安装nodepython
node版本管理 linux
打包完上传文件 webpack
... 插件缺啥按啥git
建两个任务web
一、一个跑测试(这个能够包含第二个 我的喜爱)
建任务
二、一个跑部署
建任务
gitlab配置
gitlab webhook配置 箭头填写上面👆画圈地方
最后,写的不对的地方,欢迎大佬更正