Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 31 additions & 7 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
version: 2
jobs:
build:
test:
docker:
- image: circleci/node:lts
working_directory: ~/repo
Expand All @@ -14,14 +14,15 @@ jobs:
paths:
- node_modules
key: v1-dependencies-{{ checksum "yarn.lock" }}
- run: cd giraffe && yarn run lint
- run: cd giraffe && yarn run typecheck
- run: cd giraffe && yarn run test --collectCoverage
- run: cd giraffe && yarn run build
- run: cd stories && yarn run lint
- run: cd stories && yarn run typecheck
- run: yarn lint
- run: yarn --cwd giraffe test --collectCoverage
- run: yarn --cwd giraffe build
# todo: stories-test runs lint too (lint runs two multiple times)
- run: yarn --cwd stories test
- store_artifacts:
path: giraffe/coverage
- store_artifacts:
path: stories/cypress/snapshots/**/__diff_output__
# See: https://github.com/influxdata/giraffe/issues/129
# - run:
# name: chromatic
Expand All @@ -34,3 +35,26 @@ jobs:
# else \
# yarn run chromatic -- --auto-accept-changes
# fi
update-snapshots:
docker:
- image: circleci/node:lts
working_directory: ~/repo
steps:
- checkout
- restore_cache:
keys:
- v1-dependencies-{{ checksum "yarn.lock" }}
- run: yarn install --frozen-lockfile
- run: yarn --cwd stories cy:update


workflows:
version: 2
test:
jobs:
- test
- update-snapshots:
type: approval
requires:
- test

4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@ dist
.env
.vscode
coverage

__diff_output__
videos
screenshots
4 changes: 4 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,7 @@ Then from the root of the repo, run the publish script:
InfluxData takes security and our user's trust very seriously.
If you believe you have found a security issue in any of our open source projects, please responsibly disclose it by contacting [email protected].
More details about security vulnerability reporting, including our GPG key, [can be found here](https://www.influxdata.com/how-to-report-security-vulnerabilities/).

## Cypress

- TODO
13 changes: 8 additions & 5 deletions giraffe/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@
"license": "MIT",
"scripts": {
"build": "rm -rf dist && NODE_ENV=production webpack --config webpack.config.js",
"lint": "eslint '{src,../stories/src}/**/*.{ts,tsx}'",
"prettier": "prettier --config ../.prettierrc.json --check '{src,../stories/src}/**/*.{ts,tsx}'",
"prettier:fix": "prettier --config ../.prettierrc.json --write '{src,../stories/src}/**/*.{ts,tsx}'",
"lint": "run-s typecheck eslint prettier",
"lint:fix": "run-s typecheck eslint:fix prettier:fix",
"typecheck": "tsc --noEmit --pretty",
"eslint": "eslint \"{,../stories}/{src,cypress}/**/*.{ts,tsx}\"",
"eslint:fix": "eslint \"{,../stories}/{src,cypress}/**/*.{ts,tsx}\" --fix",
"prettier": "prettier --config ../.prettierrc.json --check \"{,../stories}/{src,cypress}/**/*.{ts,tsx}\"",
"prettier:fix": "prettier --config ../.prettierrc.json --write \"{,../stories}/{src,cypress}/**/*.{ts,tsx}\"",
"publish": "echo 'To publish giraffe, run ./publish $version'",
"start": "webpack --config webpack.config.js --watch --progress",
"test": "jest --collectCoverage --maxWorkers=2",
"test:watch": "jest --collectCoverage --watch --verbose false",
"typecheck": "tsc --noEmit --pretty"
"test:watch": "jest --collectCoverage --watch --verbose false"
},
"keywords": [
"band",
Expand Down
12 changes: 8 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@
"private": true,
"workspaces": ["giraffe", "stories"],
"scripts": {
"lint": "eslint '{giraffe,stories}/src/**/*.{ts,tsx}'",
"prettier": "prettier --config .prettierrc.json --check '{giraffe,stories}/**/*.{ts,tsx}'",
"prettier:fix": "prettier --config .prettierrc.json --write '{giraffe,stories}/**/*.{ts,tsx}'",
"publish": "echo 'To publish giraffe, run ./giraffe/publish $version'"
"lint": "run-s typecheck eslint prettier",
"lint:fix": "run-s typecheck eslint:fix prettier:fix",
"typecheck": "tsc --noEmit --pretty",
"eslint": "eslint \"{giraffe,stories}/{src,cypress}/**/*.{ts,tsx}\"",
"eslint:fix": "eslint \"{giraffe,stories}/{src,cypress}/**/*.{ts,tsx}\" --fix",
"prettier": "prettier --config .prettierrc.json --check \"{giraffe,stories}/{src,cypress}/**/*.{ts,tsx}\"",
"prettier:fix": "prettier --config .prettierrc.json --write \"{giraffe,stories}/{src,cypress}/**/*.{ts,tsx}\"",
"publish": "echo \"To publish giraffe, run ./giraffe/publish $version\""
}
}
4 changes: 4 additions & 0 deletions stories/cypress.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"$schema": "https://on.cypress.io/cypress.schema.json",
"baseUrl": "http://localhost:50000/?path=/story/"
}
29 changes: 29 additions & 0 deletions stories/cypress/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/* eslint @typescript-eslint/no-unused-vars: "off" */
import 'jest'

import {
getByTestID,
getByInputName,
getByInputValue,
getByTitle,
getByTestIDSubStr,
visitTest,
snapshotComponent,
inputKnobs,
} from './support/commands'

declare global {
namespace Cypress {
interface Chainable {

getByTestID: typeof getByTestID
getByInputName: typeof getByInputName
getByInputValue: typeof getByInputValue
getByTitle: typeof getByTitle
getByTestIDSubStr: typeof getByTestIDSubStr
visitTest: typeof visitTest
snapshotComponent: typeof snapshotComponent
inputKnobs: typeof inputKnobs
}
}
}
62 changes: 62 additions & 0 deletions stories/cypress/integration/test.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@

describe('testing test', () => {
it('should make Gauge snapshot', () => {
cy.visitTest('Gauge', 'Gauge')
cy.inputKnobs('Fixed data', true, 'boolean')
})

it('should make snapshot of gauge', () => {
cy.visitTest('Gauge', 'Gauge')
cy.inputKnobs('Fixed data', true, 'boolean')
cy.inputKnobs('Gauge Lines', 12, 'number')
cy.wait(4000)
cy.inputKnobs('Ticks between lines', 3, 'number')

cy.snapshotComponent('gauge-test-3-ticks-between-lines-12-gauge-lines')

cy.inputKnobs('Gauge Min', 10, 'number')

cy.inputKnobs('Prefix', 'haf ', 'text')
cy.wait(2000)

cy.snapshotComponent('gauge-test-Haf-prefix-10-gauge-min')
})

it('should make snapshot of gauge', () => {
cy.visitTest('Gauge', 'Gauge')
cy.inputKnobs('Fixed data', true, 'boolean')

cy.inputKnobs('Ticks between lines', 3, 'number')

cy.snapshotComponent('gauge-test-3-ticks-between-lines')
cy.wait(2000)

cy.inputKnobs('Gauge Max', 23, 'number')
cy.inputKnobs('Suffix', 'HKS', 'text')
cy.wait(2000)
cy.inputKnobs('Suffix', 'halsper ', 'text')

cy.snapshotComponent('gauge-test-suffix-prefix-type')


})

it('should make snapchot of gauge', () => {
cy.visitTest('Gauge', 'Gauge')
cy.inputKnobs('Fixed data', true, 'boolean')

cy.inputKnobs('Decimal Places', 1, 'number')
cy.wait(3000)

cy.inputKnobs('Gauge Lines', 1, 'number')
cy.inputKnobs('Ticks between lines', 39, 'number')

cy.inputKnobs('TickPrefix', 'kdfakdhj', 'text')
cy.snapshotComponent('gauge-test-tick-prefix')

cy.inputKnobs('TickPrefix', ' ', 'text')
cy.inputKnobs('TickSuffix', 'kdkdhj', 'text')
cy.snapshotComponent('gaure-test-ticksSuffix')
}
)
})
24 changes: 24 additions & 0 deletions stories/cypress/plugins/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/// <reference types="cypress" />
// ***********************************************************
// 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 {addMatchImageSnapshotPlugin} = require('cypress-image-snapshot/plugin')

/**
* @type {Cypress.PluginConfig}
*/
module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
addMatchImageSnapshotPlugin(on, config)
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
139 changes: 139 additions & 0 deletions stories/cypress/support/commands.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import {addMatchImageSnapshotCommand} from 'cypress-image-snapshot/command'
import {Options as ImageSnapshotOptions} from 'cypress-image-snapshot'

addMatchImageSnapshotCommand()

// DOM node getters
export const getByTestID = (
dataTest: string,
options?: Partial<
Cypress.Loggable & Cypress.Timeoutable & Cypress.Withinable & Cypress.Shadow
>
): Cypress.Chainable => {
return cy.get(`[data-testid="${dataTest}"]`, options)
}

export const getByTestIDSubStr = (dataTest: string): Cypress.Chainable => {
return cy.get(`[data-testid*="${dataTest}"]`)
}

export const getByInputName = (name: string): Cypress.Chainable => {
return cy.get(`input[name=${name}]`)
}

export const getByInputValue = (value: string): Cypress.Chainable => {
return cy.get(`input[value='${value}']`)
}

export const getByTitle = (name: string): Cypress.Chainable => {
return cy.get(`[title="${name}"]`)
}

/**
* name is tab group name, storiname is tab name.
*/
export const visitTest = (name: string, storyname: string) => {
/** format string to stories url format */
const f = (str: string) =>
str
.replace(/ /g, '-')
.replace(/:/g, '')
.toLowerCase()
cy.visit(`${f(name)}--${f(storyname)}`)
}

// todo: replace waitings with reasonable checks(of iframe)
/**
* check snapshot of component with existing
*/
export const snapshotComponent = (
snapshotName: string,
options: ImageSnapshotOptions = {}
) => {
// cy.get("iframe").its("0.contentDocument").should('exist')
// .its('body').should('not.be.undefined')
// .its(`p[content*='placeholder for']`).contains

// enter full screen component
cy.wait(1_000)
// todo: better selector for zoom button
cy.get('.css-pvky73 > span > button').click()

cy.wait(1_000)
cy.matchImageSnapshot(snapshotName, options)

// exit full screen component
cy.get('.css-pvky73 > span > button').click()
cy.wait(1_000)
}

export const inputKnobs: {
(label: string, value: string): void
(label: string, value: string, type: 'text'): void
(label: string, value: string, type: 'select'): void
(label: string, value: number, type: 'number'): void
(label: string, value: boolean, type: 'boolean'): void
} = (
label: string,
value: number | string | boolean,
type: 'range' | 'select' | 'number' | 'text' | 'boolean' = 'text'
) => {
const escapeSpaces = (str: string) => str.replace(/ /, '\\ ')
const selector = `#${escapeSpaces(label)}, [name='${label}']`
switch (type) {
case 'text':
const valueStr = value as string
cy.get(selector)
.clear({force: true})
.type(valueStr, {force: true})
break
case 'number':
cy.get(selector)
.clear({force: true})
.type((value as number).toString(), {force: true})
break
case 'select':
cy.get(selector).select(value as string)
break
case 'boolean':
cy.get(selector + ' input')[value ? 'check' : 'uncheck']()
break
case 'range':
throw new Error(`Input knobs of type ${type} not implemented`)
// todo: input - range
// cy.get(`[name='${escapeSpaces(label)}']`)
// // .then(x => {
// // x.first().trigger("change", {value})
// // })
// // .invoke('val', value)
// // .invoke('attr', 'value', value)
// // .trigger('input', { force: true, data: value })
// // .trigger('change', { force: true, value })
// // .invoke('mouseup')
// // .trigger('blur')
// // .type(100)
// // .trigger('mousedown', { which: 1 })
// // .trigger('mousemove', { clientX: 0, clientY: 100 })
// // .trigger('mouseup', {force: true})
// cy.wait(1000)
// break
default:
throw new Error(`Input knobs of type ${type} not implemented`)
}
}

/* eslint-disable */

// getters
Cypress.Commands.add('getByTestID', getByTestID)
Cypress.Commands.add('getByInputName', getByInputName)
Cypress.Commands.add('getByInputValue', getByInputValue)
Cypress.Commands.add('getByTitle', getByTitle)
Cypress.Commands.add('getByTestIDSubStr', getByTestIDSubStr)

// storybook helpers
Cypress.Commands.add('visitTest', visitTest)
Cypress.Commands.add('snapshotComponent', snapshotComponent)
Cypress.Commands.add('inputKnobs', inputKnobs)

/* eslint-enable */
Loading