Add visual regression testing with cypress

Signed-off-by: Raimund Schlüßler <raimund.schluessler@mailbox.org>
This commit is contained in:
Raimund Schlüßler 2020-08-23 22:18:36 +02:00 коммит произвёл John Molakvoæ (skjnldsv)
Родитель 61ab3d21db
Коммит 27c0c29302
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 60C25B8C072916CF
59 изменённых файлов: 3175 добавлений и 4 удалений

53
.github/workflows/cypress.yml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,53 @@
name: Cypress
on:
pull_request:
push:
branches:
- master
- stable*
env:
APP_NAME: nextcloud-vue
jobs:
cypress:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# run x copies of the current job in parallel
containers: [1]
node-version: ['12']
name: Runner ${{ matrix.containers }}
steps:
- uses: actions/checkout@v2
- name: Set up node ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Install dependencies
run: npm ci
- name: Cypress run
uses: cypress-io/github-action@v1
with:
record: true
parallel: true
tag: ${{ github.event_name }}
env:
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
# https://github.com/cypress-io/github-action/issues/124
COMMIT_INFO_MESSAGE: ${{ github.event.pull_request.title }}
- name: Upload snapshots
uses: actions/upload-artifact@v2
if: always()
with:
name: snapshots
path: cypress/snapshots

5
.gitignore поставляемый
Просмотреть файл

@ -25,3 +25,8 @@ coverage
# Docs compiled build
styleguide/build/
styleguide/index.html
# Cypress files
cypress/videos
cypress/screenshots
cypress/snapshots/actual

15
cypress.json Normal file
Просмотреть файл

@ -0,0 +1,15 @@
{
"projectId": "3paxvy",
"viewportWidth": 1920,
"viewportHeight": 1080,
"defaultCommandTimeout": 6000,
"experimentalComponentTesting": true,
"componentFolder": "tests/visual",
"nodeVersion": "system",
"env": {
"failSilently": false,
"type": "actual"
},
"screenshotsFolder": "cypress/snapshots/actual",
"trashAssetsBeforeRuns": true
}

31
cypress/plugins/index.js Normal file
Просмотреть файл

@ -0,0 +1,31 @@
// ***********************************************************
// This example plugins/index.js can be used to load plugins
//
// You can change the location of this file or turn off loading
// the plugins file with the 'pluginsFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/plugins-guide
// ***********************************************************
// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)
const getCompareSnapshotsPlugin = require('cypress-visual-regression/dist/plugin')
const webpack = require('@cypress/webpack-preprocessor')
const webpackOptions = require('../../webpack.dev.js')
webpackOptions.externals = {}
const options = {
// send in the options from your webpack.config.js, so it works the same
// as your app's code
webpackOptions,
watchOptions: {},
}
module.exports = (on, config) => {
getCompareSnapshotsPlugin(on)
on('file:preprocessor', webpack(options))
}

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 7.7 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.6 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.7 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.7 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.0 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.8 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.7 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.7 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 7.4 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.3 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.4 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.4 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.9 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.7 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.4 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.4 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 7.7 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.5 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.7 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.7 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.2 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.0 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.7 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.7 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.8 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.2 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.1 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.5 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.7 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.6 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.1 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.5 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.6 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.0 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.9 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.3 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.7 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.5 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.9 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.3 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.8 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.2 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.0 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.5 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.9 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.8 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.0 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.5 KiB

Просмотреть файл

@ -0,0 +1,3 @@
const compareSnapshotCommand = require('cypress-visual-regression/dist/command')
compareSnapshotCommand()

17
cypress/support/index.js Normal file
Просмотреть файл

@ -0,0 +1,17 @@
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
import 'cypress-vue-unit-test/dist/support'
import './commands'

2931
package-lock.json сгенерированный

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -23,7 +23,10 @@
"stylelint": "stylelint src/**/*.vue src/**/*.scss src/**/*.css",
"stylelint:fix": "stylelint src/**/*.vue src/**/*.scss src/**/*.css --fix",
"styleguide": "vue-styleguidist server",
"styleguide:build": "vue-styleguidist build"
"styleguide:build": "vue-styleguidist build",
"cypress": "cypress run",
"cypress:gui": "cypress open",
"cypress:update-snapshots": "cypress run --env type=base --config screenshotsFolder=cypress/snapshots/base"
},
"main": "dist/ncvuecomponents.js",
"files": [
@ -70,15 +73,20 @@
"babel-jest": "^26.3.0",
"babel-loader": "^8.1.0",
"css-loader": "^3.5.2",
"cypress": "^5.0.0",
"cypress-visual-regression": "^1.5.0",
"cypress-vue-unit-test": "^3.5.1",
"eslint": "^6.8.0",
"eslint-config-standard": "^14.1.1",
"eslint-loader": "^4.0.2",
"eslint-plugin-cypress": "^2.11.1",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.1",
"eslint-plugin-vue": "^6.2.2",
"file-loader": "^6.0.0",
"fontsource-roboto": "^3.0.3",
"gettext-extractor": "^3.5.2",
"gettext-parser": "^4.0.3",
"glob": "^7.1.6",

Просмотреть файл

@ -1,5 +1,9 @@
module.exports = {
env: {
jest: true
}
jest: true,
"cypress/globals": true
},
extends: [
"plugin:cypress/recommended"
],
}

Просмотреть файл

@ -0,0 +1,103 @@
/**
* @copyright Copyright (c) 2020 Raimund Schlüßler <raimund.schluessler@mailbox.org>
*
* @author Raimund Schlüßler <raimund.schluessler@mailbox.org>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
import { mount } from 'cypress-vue-unit-test'
// import Vue from 'vue'
import AppSidebar from '../../../../src/components/AppSidebar/AppSidebar.vue'
import ActionButton from '../../../../src/components/ActionButton/ActionButton.vue'
// Server CSS styles
import server from '../../../../styleguide/assets/server.css'
import icons from '../../../../styleguide/assets/icons.css'
import variables from '../../../../styleguide/assets/variables.css'
// Import font so CI has the same
import 'fontsource-roboto'
describe('AppSidebar.vue', () => {
'use strict'
/**
* We need this custom style because we run the AppSidebar component without a Content component,
* which applies this rule:
* https://github.com/nextcloud/nextcloud-vue/blob/master/src/components/Content/Content.vue#L73-L75
*/
const style = `
* {
box-sizing: border-box;
}
`
// Load the server CSS styles
const cssFiles = [server, icons, variables]
// Possible props and actions
const starred = [null, false, true]
const compact = [false, true]
const header = ['', '<div style="background: no-repeat center/contain var(--icon-folder-000); height: 100%;" />']
const secondary = ['', '<ActionButton icon="icon-delete">Action1</ActionButton><ActionButton icon="icon-delete">Action2</ActionButton>']
const components = {
ActionButton,
}
// extend Vue with global components
const extensions = {
components,
}
starred.forEach(star => {
compact.forEach(comp => {
header.forEach(head => {
secondary.forEach(second => {
const fileName = `AppSidebar.vue
- starred_${star === null ? 'null' : star ? 'true' : 'false'}
- compact_${comp ? 'true' : 'false'}
- header_${head ? 'image' : 'none'}
- secondary_${second ? 'button' : 'none'}
`.replace(/(\n|\t)/gi, '')
const defaultOptions = {
propsData: {
title: 'Sidebar title.',
subtitle: 'subtitle',
starred: star,
compact: comp,
},
slots: {
default: ['<div />'],
header: head,
'secondary-actions': second,
},
style,
cssFiles,
extensions,
}
it('Renders ' + fileName, () => {
mount(AppSidebar, defaultOptions)
cy.get('.app-sidebar-header').compareSnapshot(fileName)
})
})
})
})
})
})

Просмотреть файл

@ -13,7 +13,8 @@ const { DefinePlugin } = require('webpack')
const nodeExternals = require('webpack-node-externals')
// scope variable
const appVersion = JSON.stringify(process.env.npm_package_version)
// fallback for cypress testing
const appVersion = JSON.stringify(process.env.npm_package_version || 'nextcloud-vue')
const versionHash = md5(appVersion).substr(0, 7)
const SCOPE_VERSION = JSON.stringify(versionHash)
const ICONFONT_NAME = `iconfont-vue-${versionHash}`