Skip to content

Commit

Permalink
Feature: Mobile - Add a basic editor field
Browse files Browse the repository at this point in the history
  • Loading branch information
sheremet-va committed May 11, 2022
1 parent 47798e3 commit 1e428e6
Show file tree
Hide file tree
Showing 53 changed files with 3,381 additions and 121 deletions.
22 changes: 22 additions & 0 deletions .cypress/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"pluginsFile": "plugins/index.js",
"supportFile": "support/index.js",
"fixturesFolder": "fixtures",
"integrationFolder": "integration",
"downloadsFolder": "downloads",
"screenshotsFolder": "screenshots",
"videosFolder": "videos",
"videoCompression": false,
"fileServerFolder": "..",
"retries": {
"runMode": 2,
"openMode": 0
},
"component": {
"//": "iPhone 12 Viewport",
"viewportHeight": 844,
"viewportWidth": 390,
"componentFolder": "../app/frontend/cypress",
"testFiles": "**/*.cy.{js,jsx,ts,tsx}"
}
}
5 changes: 5 additions & 0 deletions .cypress/fixtures/example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "Using fixtures to represent data",
"email": "[email protected]",
"body": "Fixtures are a great way to mock data for responses to routes"
}
Binary file added .cypress/fixtures/example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions .cypress/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"private": true,
"devDependencies": {
"@cypress/vite-dev-server": "^2.2.2",
"@cypress/vue": "^3.1.2",
"@testing-library/cypress": "^8.0.2",
"cypress": "^9.6.0",
"cypress-image-snapshot": "^4.0.1",
"cypress-real-events": "^1.7.0"
}
}
53 changes: 53 additions & 0 deletions .cypress/plugins/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/

const { startDevServer } = require('@cypress/vite-dev-server')
const { addMatchImageSnapshotPlugin } = require('cypress-image-snapshot/plugin')
const { rm } = require('fs/promises')
const { readFileSync } = require('fs')
const { resolve } = require('path')

module.exports = function plugin(on, config) {
const pkgFile = readFileSync(resolve(__dirname, '../../package.json'), 'utf8')
const pkg = JSON.parse(pkgFile)
const cypressPkgFile = readFileSync(
resolve(__dirname, '../package.json'),
'utf8',
)
const cypressPkg = JSON.parse(cypressPkgFile)

on('dev-server:start', (options) => {
const isCI = !!process.env.CI
const root = resolve(__dirname, '..', '..')
const viteConfig = {
mode: 'cypress',
root,
configFile: resolve(__dirname, '..', '..', 'vite.config.ts'),
cacheDir: resolve(__dirname, '..', 'node_modules', '.vite'),
server: {
fs: {
strict: false,
},
hmr: !isCI,
},
optimizeDeps: {
entries: [
'**/.cypress/utils/*.ts',
'**/cypress/**/*.ts',
'!**/node_modules/**',
'!**/*.d.ts',
],
},
}
return startDevServer({
options: { ...options, config: { ...options.config, projectRoot: root } },
viteConfig,
})
})
// eslint-disable-next-line consistent-return
on('after:spec', (spec, results) => {
if (results && results.stats.failures === 0 && results.video) {
return rm(results.video)
}
})
addMatchImageSnapshotPlugin(on, config)
}
84 changes: 84 additions & 0 deletions .cypress/support/commands.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/

import '@testing-library/cypress/add-commands'
import 'cypress-real-events/support'
import { configure } from '@testing-library/cypress'
import { addMatchImageSnapshotCommand } from 'cypress-image-snapshot/command'

addMatchImageSnapshotCommand({
customSnapshotsDir: 'snapshots',
})
configure({ testIdAttribute: 'data-test-id' })

/**
* Simulates a paste event.
* Modified from https://gist.github.com/nickytonline/bcdef8ef00211b0faf7c7c0e7777aaf6
*
* @param subject A jQuery context representing a DOM element.
* @param pasteOptions Set of options for a simulated paste event.
* @param pasteOptions.pastePayload Simulated data that is on the clipboard.
* @param pasteOptions.pasteFormat The format of the simulated paste payload. Default value is 'text'.
* @param pasteOptions.files A list of assisiated file, if any
*
* @returns The subject parameter.
*
* @example
* cy.get('body').paste({
* pasteType: 'application/json',
* pastePayload: {hello: 'yolo'},
* });
*/
Cypress.Commands.add(
'paste',
{ prevSubject: true },
function onPaste(subject, pasteOptions) {
const { pastePayload = '', pasteType = 'text', files = [] } = pasteOptions
const data =
pasteType === 'application/json'
? JSON.stringify(pastePayload)
: pastePayload
// https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer
const clipboardData = new DataTransfer()
clipboardData.setData(pasteType, data)
files.forEach((file) => {
clipboardData.items.add(file)
})
// https://developer.mozilla.org/en-US/docs/Web/API/Element/paste_event
const pasteEvent = new ClipboardEvent('paste', {
bubbles: true,
cancelable: true,
dataType: pasteType,
data,
clipboardData,
})
subject[0].dispatchEvent(pasteEvent)

return subject
},
)

Cypress.Commands.add(
'selectText',
{ prevSubject: true },
(subject, direction, size) => {
return cy
.wrap(subject)
.realPress([
'Shift',
...new Array(size).fill(
direction === 'right' ? 'ArrowRight' : 'ArrowLeft',
),
])
},
)

Cypress.Commands.overwrite('screenshot', (original, ...args) => {
const root = document.querySelector('body')

root.style.setProperty('font-family', 'Helvetica')
const result = original(...args)
result.then(() => {
root.style.removeProperty('font-family')
})
return result
})
11 changes: 11 additions & 0 deletions .cypress/support/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/

import '@mobile/styles/main.css'
import 'virtual:svg-icons-register' // eslint-disable-line import/no-unresolved

import './commands'

document.body.className = 'bg-black text-white'

// eslint-disable-next-line no-underscore-dangle
window.__ = (str) => str
42 changes: 42 additions & 0 deletions .cypress/types/commands.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/

declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace Cypress {
interface Chainable<Subject> {
/**
* Simulates a paste event.
* Modified from https://gist.github.com/nickytonline/bcdef8ef00211b0faf7c7c0e7777aaf6
*
* @param subject A jQuery context representing a DOM element.
* @param pasteOptions Set of options for a simulated paste event.
* @param pasteOptions.pastePayload Simulated data that is on the clipboard.
* @param pasteOptions.pasteFormat The format of the simulated paste payload. Default value is 'text'.
* @param pasteOptions.files A list of assisiated file, if any
*
* @returns The subject parameter.
*
* @example
* cy.get('body').paste({
* pasteType: 'application/json',
* pastePayload: {hello: 'yolo'},
* });
*/
paste(options: {
pastePayload?: string
pasteFormat?: string
files?: File[]
}): Chainable<Subject>
selectText(direction: 'left' | 'right', size: number): Chainable<Subject>
matchImageSnapshot(
options?: Partial<Loggable & Timeoutable & ScreenshotOptions>,
): Chainable<null>
matchImageSnapshot(
fileName: string,
options?: Partial<Loggable & Timeoutable & ScreenshotOptions>,
): Chainable<null>
}
}
}

export {}
25 changes: 25 additions & 0 deletions .cypress/utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/

import { mount } from '@cypress/vue'
import { merge } from 'lodash-es'
import { plugin as formPlugin } from '@formkit/vue'

import { buildFormKitPluginConfig } from '@shared/form'
import initializeGlobalComponents from '@shared/initializer/globalComponents'

// imported only for types
// for some reason adding it to tsconfig doesn't work
import '@testing-library/cypress'
import 'cypress-real-events'
import '../types/commands'

// TODO
// @ts-expect-error untyped arguments
export const mountComponent: typeof mount = (component, options) => {
const plugins = []
plugins.push(initializeGlobalComponents)
plugins.push([formPlugin, buildFormKitPluginConfig()])
return mount(component, merge({ global: { plugins } }, options))
}

export default {}
Loading

0 comments on commit 1e428e6

Please sign in to comment.