Take percy snapshots of storybooks (#10622)

This commit is contained in:
Felix Becker 2020-05-14 13:15:42 +02:00 committed by GitHub
parent dd8e65d3ba
commit bb2040851d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 321 additions and 167 deletions

View File

@ -26,3 +26,4 @@ shared/dev/**/*.js
client/contrib/GH2SG.bookmarklet.js
docker-images/grafana/jsonnet/*.json
docker-images/grafana/grafonnet-lib/
!/.storybook/**

View File

@ -1,3 +0,0 @@
import '@storybook/addon-actions/register'
import '@storybook/addon-knobs/register'
import '@storybook/addon-options/register'

View File

@ -1,39 +0,0 @@
import { configureActions } from '@storybook/addon-actions'
// @ts-ignore
import { withConsole } from '@storybook/addon-console'
import { withInfo } from '@storybook/addon-info'
import { withKnobs } from '@storybook/addon-knobs'
import { addDecorator, addParameters, configure } from '@storybook/react'
import { themes } from '@storybook/theming'
import { setLinkComponent, AnchorLink } from '../shared/src/components/Link'
setLinkComponent(AnchorLink)
async function main(): Promise<void> {
// Webpack provides require.context. TODO: If this is run in Jest in the future, we'll need to
// use babel-plugin-require-context-hook.
const requireContexts = [
require.context('../shared', true, /\.story\.tsx?$/),
require.context('../browser', true, /\.story\.tsx?$/),
require.context('../web', true, /\.story\.tsx?$/),
]
for (const requireContext of requireContexts) {
for (const storyModule of requireContext.keys()) {
requireContext(storyModule)
}
}
// Configure storybooks.
configure(() => {
addDecorator((storyFn, context) => withKnobs(storyFn, context))
addDecorator((storyFn, context) => withConsole()(storyFn)(context))
addParameters({ theme: themes.dark })
addDecorator(withInfo({ header: false, propTables: false }))
configureActions({
depth: 100,
limit: 20,
})
}, module)
}
main().catch(err => console.error(err))

View File

@ -0,0 +1,20 @@
import initStoryshots from '@storybook/addon-storyshots'
import { puppeteerTest } from '@storybook/addon-storyshots-puppeteer'
import * as path from 'path'
import { pathToFileURL } from 'url'
import { recordCoverage } from '../shared/src/e2e/coverage'
// This test suite does not actually test anything.
// It just loads up the storybook in Puppeteer and records its coverage,
// so it can be tracked in Codecov.
initStoryshots({
configPath: __dirname,
suite: 'Storybook',
test: puppeteerTest({
storybookUrl: pathToFileURL(path.resolve(__dirname, '../storybook-static')).href,
testBody: async page => {
await recordCoverage(page.browser())
},
}),
})

14
.storybook/jest.config.js Normal file
View File

@ -0,0 +1,14 @@
// @ts-check
const config = require('../jest.config.base')
const exportedConfig = {
...config,
displayName: 'storybooks',
rootDir: __dirname,
collectCoverage: false, // Collected through Puppeteer
roots: ['<rootDir>'],
verbose: true,
}
module.exports = exportedConfig

61
.storybook/main.js Normal file
View File

@ -0,0 +1,61 @@
const path = require('path')
const { remove } = require('lodash')
const { DefinePlugin, ProgressPlugin } = require('webpack')
const config = {
stories: ['../**/*.story.tsx'],
addons: ['@storybook/addon-knobs', '@storybook/addon-actions', '@storybook/addon-options'],
/**
* @param config {import('webpack').Configuration}
* @returns {import('webpack').Configuration}
*/
webpackFinal: config => {
// Include sourcemaps
config.mode = 'development'
const definePlugin = config.plugins.find(plugin => plugin instanceof DefinePlugin)
// @ts-ignore
definePlugin.definitions.NODE_ENV = JSON.stringify('development')
// @ts-ignore
definePlugin.definitions['process.env'].NODE_ENV = JSON.stringify('development')
// We don't use Storybook's default config for our repo, it doesn't handle TypeScript.
config.module.rules.splice(0, 1)
if (process.env.CI) {
remove(config.plugins, plugin => plugin instanceof ProgressPlugin)
}
config.module.rules.push({
test: /\.tsx?$/,
loader: require.resolve('babel-loader'),
options: {
configFile: path.resolve(__dirname, '..', 'babel.config.js'),
},
})
config.resolve.extensions.push('.ts', '.tsx')
// Put our style rules at the beginning so they're processed by the time it
// gets to storybook's style rules.
config.module.rules.unshift({
test: /\.(css|sass|scss)$/,
use: [
'to-string-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
sassOptions: {
includePaths: [path.resolve(__dirname, '..', 'node_modules')],
},
},
},
],
// Make sure Storybook styles get handled by the Storybook config
exclude: /node_modules\/@storybook\//,
})
return config
},
}
module.exports = config

16
.storybook/preview.js Normal file
View File

@ -0,0 +1,16 @@
import { configureActions } from '@storybook/addon-actions'
import { withConsole } from '@storybook/addon-console'
import { withInfo } from '@storybook/addon-info'
import { withKnobs } from '@storybook/addon-knobs'
import { addDecorator } from '@storybook/react'
import { setLinkComponent, AnchorLink } from '../shared/src/components/Link'
setLinkComponent(AnchorLink)
// Don't know why this type doesn't work, but this is the correct usage
// @ts-ignore
addDecorator(withInfo({ header: false, propTables: false }))
addDecorator(withKnobs)
addDecorator((storyFn, context) => withConsole()(storyFn)(context))
configureActions({ depth: 100, limit: 20 })

View File

@ -1,15 +0,0 @@
// Set commonly used CSS variables that many components assume exist. This is better than importing
// all of (e.g.) SourcegraphWebApp.scss, because those styles are only applied for the web app and
// would be misleading to use for browser extension and shared component storybooks.
if (document && document.documentElement) {
// It's not necessary to define all CSS variables here or to use the precise values from our CSS.
// These are just used for storybooks.
const CSS_VARS = {
'--secondary': '#777777',
'--text-muted': '#bbbbbb',
'--primary': '#1c7ed6',
}
for (const name of Object.keys(CSS_VARS)) {
document.documentElement.style.setProperty(name, CSS_VARS[name])
}
}

View File

@ -1,39 +0,0 @@
import * as path from 'path'
import * as webpack from 'webpack'
export default ({ config }: { config: webpack.Configuration }) => {
if (!config.module || !config.resolve?.extensions) {
throw new Error('unexpected config')
}
config.module.rules.push({
test: /\.tsx?$/,
loader: require.resolve('babel-loader'),
options: {
configFile: path.resolve(__dirname, '..', 'babel.config.js'),
},
})
config.resolve.extensions.push('.ts', '.tsx')
// Put our style rules at the beginning so they're processed by the time it
// gets to storybook's style rules.
config.module.rules.unshift({
test: /\.(css|sass|scss)$/,
use: [
'to-string-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
sassOptions: {
includePaths: [path.resolve(__dirname, '..', 'node_modules')],
},
},
},
],
// Make sure Storybook styles get handled by the Storybook config
exclude: /node_modules\/@storybook\//,
})
return config
}

View File

@ -29,6 +29,6 @@ comment:
# Exceptions:
# - PRs that only update docs, we don't need Codecov there.
# - e2e tests, which don't run on most PRs.
after_n_builds: 5
after_n_builds: 6
ignore:
- '**/bindata.go'

View File

@ -107,8 +107,18 @@ func addSharedTests(pipeline *bk.Pipeline) {
bk.Cmd("dev/ci/yarn-test.sh shared"),
bk.Cmd("bash <(curl -s https://codecov.io/bash) -c -F typescript -F unit"))
// Storybook
pipeline.AddStep(":storybook:", bk.Cmd("dev/ci/yarn-run.sh storybook:smoke-test"))
// Storybook coverage
pipeline.AddStep(":storybook::codecov:",
bk.Env("PUPPETEER_SKIP_CHROMIUM_DOWNLOAD", ""),
bk.Cmd("COVERAGE_INSTRUMENT=true dev/ci/yarn-run.sh build-storybook"),
bk.Cmd("yarn run cover-storybook"),
bk.Cmd("yarn nyc report -r json"),
bk.Cmd("bash <(curl -s https://codecov.io/bash) -c -F typescript -F storybook"))
// Upload storybook to Percy
pipeline.AddStep(":storybook::percy:",
bk.Env("PUPPETEER_SKIP_CHROMIUM_DOWNLOAD", ""),
bk.Cmd("dev/ci/yarn-run.sh build-storybook percy-storybook"))
}
// Adds PostgreSQL backcompat tests.

View File

@ -11,7 +11,7 @@ const config = {
collectCoverage: !!process.env.CI,
collectCoverageFrom: ['<rootDir>/src/**/*.{ts,tsx}'],
coverageDirectory: '<rootDir>/coverage',
coveragePathIgnorePatterns: [/\.(test|story)\.tsx?$/.source, /\.d\.ts$/.source],
coveragePathIgnorePatterns: [/\/node_modules\//.source, /\.(test|story)\.tsx?$/.source, /\.d\.ts$/.source],
roots: ['<rootDir>/src'],
// Transform packages that do not distribute CommonJS packages (typically because they only distribute ES6

View File

@ -10,5 +10,6 @@ module.exports = {
'shared/jest.config.js',
'web/jest.config.js',
'cmd/precise-code-intel/jest.config.js',
'.storybook/jest.config.js',
],
}

View File

@ -20,12 +20,13 @@
"graphql": "gulp graphQLTypes",
"graphql-lint": "graphql-schema-linter --old-implements-syntax --comment-descriptions cmd/frontend/graphqlbackend/schema.graphql",
"prepublish": "gulp generate",
"test": "jest --testPathIgnorePatterns e2e regression integration",
"test": "jest --testPathIgnorePatterns e2e regression integration storybook",
"test-e2e": "TS_NODE_PROJECT=web/src/e2e/tsconfig.json mocha ./web/src/e2e/e2e.test.ts",
"cover-e2e": "nyc --hook-require=false yarn test-e2e",
"storybook": "start-storybook -p 9001 -c .storybook",
"storybook:build": "build-storybook -c .storybook",
"storybook:smoke-test": "yarn run storybook --smoke-test",
"build-storybook": "build-storybook -c .storybook",
"cover-storybook": "nyc --hook-require=false yarn jest .storybook/coverage",
"percy-storybook": "PERCY_TOKEN=${PERCY_STORYBOOK_TOKEN} percy-storybook --widths=768",
"deduplicate": "yarn-deduplicate -s fewer"
},
"browserslist": [
@ -37,13 +38,14 @@
"not IE > 0"
],
"nyc": {
"extends": "@istanbuljs/nyc-config-typescript",
"all": true,
"extension": [
".tsx",
".ts"
],
"include": [
"@(web|shared)/src/**/*.ts?(x)"
"@(web|shared|browser)/src/**/*.ts?(x)"
],
"exclude": [
"node_modules",
@ -72,8 +74,10 @@
"@babel/runtime": "^7.9.6",
"@gql2ts/from-schema": "^1.10.1",
"@gql2ts/language-typescript": "^1.9.0",
"@istanbuljs/nyc-config-typescript": "^1.0.1",
"@octokit/rest": "^16.36.0",
"@percy/puppeteer": "^1.1.0",
"@percy/storybook": "^3.3.0",
"@slack/web-api": "^5.8.0",
"@sourcegraph/babel-plugin-transform-react-hot-loader-wrapper": "^1.0.0",
"@sourcegraph/eslint-config": "^0.17.2",
@ -87,6 +91,7 @@
"@storybook/addon-links": "^5.3.18",
"@storybook/addon-options": "^5.3.18",
"@storybook/addon-storyshots": "^5.3.18",
"@storybook/addon-storyshots-puppeteer": "^5.3.18",
"@storybook/addons": "^5.3.18",
"@storybook/components": "^5.3.18",
"@storybook/core": "^5.3.18",

View File

@ -122,7 +122,10 @@ export class ActivationDropdown extends React.PureComponent<ActivationDropdownPr
</span>
</MenuButton>
<MenuPopover
className={classNames('activation-dropdown', 'dropdown-menu', { show: isExpanded })}
className={classNames('activation-dropdown', 'dropdown-menu', {
show: isExpanded || this.props.alwaysShow,
})}
hidden={!(isExpanded || this.props.alwaysShow)}
portal={this.props.portal}
>
<div className="dropdown-item-text activation-dropdown-header">

View File

@ -1,5 +1,7 @@
import { Driver } from './driver'
import { writeFile, mkdir } from 'mz/fs'
import { Browser } from 'puppeteer'
import * as uuid from 'uuid'
declare global {
interface FileCoverage {
@ -16,39 +18,45 @@ declare global {
let warnedNoCoverage = false
/**
* Saves coverage recorded by the instrumented code in `.nyc_output`.
* Saves coverage recorded by the instrumented code in `.nyc_output` after each test.
*/
export function afterEachRecordCoverage(getDriver: () => Driver): void {
afterEach('Record coverage', async () => {
await mkdir('.nyc_output', { recursive: true })
// Get pages, web workers, background pages, etc.
const targets = await getDriver().browser.targets()
await Promise.all(
targets.map(async target => {
const executionContext = (await target.worker()) ?? (await target.page())
if (!executionContext) {
return
}
const coverage: typeof __coverage__ = await executionContext.evaluate(() => globalThis.__coverage__)
if (!coverage) {
if (!warnedNoCoverage && target.url() !== 'about:blank') {
console.error(
`No coverage found in target ${target.url()}\n` +
'Run the dev Sourcegraph instance with COVERAGE_INSTRUMENT=true to track coverage.'
)
warnedNoCoverage = true
}
return
}
await Promise.all(
Object.values(coverage).map(async fileCoverage => {
await writeFile(
`.nyc_output/${fileCoverage.hash}.json`,
JSON.stringify({ [fileCoverage.path]: fileCoverage })
)
})
)
})
)
})
afterEach('Record coverage', () => recordCoverage(getDriver().browser))
}
/**
* Saves coverage recorded by the instrumented code in `.nyc_output`.
*/
export async function recordCoverage(browser: Browser): Promise<void> {
await mkdir('.nyc_output', { recursive: true })
// Get pages, web workers, background pages, etc.
const targets = await browser.targets()
await Promise.all(
targets.map(async target => {
const executionContext = (await target.worker()) ?? (await target.page())
if (!executionContext) {
return
}
const coverage: typeof __coverage__ = await executionContext.evaluate(() => globalThis.__coverage__)
if (!coverage) {
if (!warnedNoCoverage && target.url() !== 'about:blank') {
console.error(
`No coverage found in target ${target.url()}\n` +
'Run the dev Sourcegraph instance with COVERAGE_INSTRUMENT=true to track coverage.'
)
warnedNoCoverage = true
}
return
}
await Promise.all(
Object.values(coverage).map(async fileCoverage => {
await writeFile(
`.nyc_output/${uuid.v4()}.json`,
JSON.stringify({ [fileCoverage.path]: fileCoverage }),
{ flag: 'wx' }
)
})
)
})
)
}

169
yarn.lock
View File

@ -1030,7 +1030,7 @@
dependencies:
regenerator-runtime "^0.13.4"
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.4", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.6":
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.4", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2", "@babel/runtime@^7.9.6":
version "7.9.6"
resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.6.tgz#a9102eb5cadedf3f31d08a9ecf294af7827ea29f"
integrity sha512-64AF1xY3OAkFHqOb9s4jpgk1Mm5vDZ4L3acHvAml+53nO1XbXLuDodsVpO4OIUsmemlUHMxNdYMNJmsvOwLrvQ==
@ -1271,6 +1271,13 @@
js-yaml "^3.13.1"
resolve-from "^5.0.0"
"@istanbuljs/nyc-config-typescript@^1.0.1":
version "1.0.1"
resolved "https://registry.npmjs.org/@istanbuljs/nyc-config-typescript/-/nyc-config-typescript-1.0.1.tgz#55172f5663b3635586add21b14d42ca94a163d58"
integrity sha512-/gz6LgVpky205LuoOfwEZmnUtaSmdk0QIMcNFj9OvxhiMhPpKftMgZmGN7jNj7jR+lr8IB1Yks3QSSSNSxfoaQ==
dependencies:
"@istanbuljs/schema" "^0.1.2"
"@istanbuljs/schema@^0.1.2":
version "0.1.2"
resolved "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd"
@ -1719,6 +1726,32 @@
dependencies:
"@percy/agent" "~0"
"@percy/react-percy-api-client@^0.4.6":
version "0.4.6"
resolved "https://registry.npmjs.org/@percy/react-percy-api-client/-/react-percy-api-client-0.4.6.tgz#e2b907c39bc0b53ce2da856aad8cec7ab03dac46"
integrity sha512-tbzw8i/iNFJpfw8m+Bgg6dGtLX5VEVyafLidw1rL+LoQ/FgiAgM9/wAzlCnPjyiF2QNaVNhkij9y6HHsNlfevQ==
dependencies:
babel-runtime "^6.26.0"
debug "^2.6.3"
es6-promise-pool "^2.4.4"
mime-types "^2.1.14"
percy-client "^3.0.0"
slugify "^1.1.0"
"@percy/storybook@^3.3.0":
version "3.3.0"
resolved "https://registry.npmjs.org/@percy/storybook/-/storybook-3.3.0.tgz#7ebdf2a0f6e09924b82045a755a2e2fbc6704581"
integrity sha512-xo6wIZUhrR07K5iTjTRUK0jXWhIYsP4yjUNjqNVwsuYS+aDD+1ZGd+2ZI0IrfTcllUkA6MUgtP1qMRhpx9hZ6g==
dependencies:
"@percy/react-percy-api-client" "^0.4.6"
babel-runtime "^6.26.0"
debug "^3.1.0"
es6-error "^4.0.2"
es6-promise-pool "^2.4.4"
puppeteer "^1.4.0"
walk "^2.3.9"
yargs "^7.0.2"
"@phenomnomnominal/tsquery@^4.0.0":
version "4.0.0"
resolved "https://registry.npmjs.org/@phenomnomnominal/tsquery/-/tsquery-4.0.0.tgz#610e8ac968137e4a0f98c842c919bb8ad0e85718"
@ -2038,7 +2071,8 @@
integrity sha512-KWxkyphmlwam8kfYPSmoitKQRMGQCsr1ZRmNZgijT7ABKaVyk/+I5ezt2J213tM04Hi0vyg4L7iH1VCkNvm2Jw==
"@sourcegraph/extension-api-types@link:packages/@sourcegraph/extension-api-types":
version "2.1.0"
version "0.0.0"
uid ""
"@sourcegraph/prettierrc@^3.0.3":
version "3.0.3"
@ -2166,6 +2200,19 @@
core-js "^3.0.1"
util-deprecate "^1.0.2"
"@storybook/addon-storyshots-puppeteer@^5.3.18":
version "5.3.18"
resolved "https://registry.npmjs.org/@storybook/addon-storyshots-puppeteer/-/addon-storyshots-puppeteer-5.3.18.tgz#11e0f5e428bddd0dcefe6d5445aa62c02722cedb"
integrity sha512-hkJXFuNwjhwwhMD6WzqkmG1FUHfzOxRg7D7EvogLRIF5cecqvA5qXt5a0zinwBeOCF9RtBQNXtL+b52wtHZBHA==
dependencies:
"@storybook/csf" "0.0.1"
"@storybook/node-logger" "5.3.18"
"@types/jest-image-snapshot" "^2.8.0"
"@wordpress/jest-puppeteer-axe" "^1.5.0"
core-js "^3.0.1"
jest-image-snapshot "^2.8.2"
regenerator-runtime "^0.13.3"
"@storybook/addon-storyshots@^5.3.18":
version "5.3.18"
resolved "https://registry.npmjs.org/@storybook/addon-storyshots/-/addon-storyshots-5.3.18.tgz#616bc93a6cc1db450baa441a52f26af24864ddfe"
@ -2981,6 +3028,13 @@
"@types/istanbul-lib-coverage" "*"
"@types/istanbul-lib-report" "*"
"@types/jest-image-snapshot@^2.8.0":
version "2.12.0"
resolved "https://registry.npmjs.org/@types/jest-image-snapshot/-/jest-image-snapshot-2.12.0.tgz#183bafbac47b8e7fb4fdf5deb613c3d5dcbb53f7"
integrity sha512-bjwLkSH/JmSjpzyUIV7lH62vEsGLGPzgf8aX+Rb11pFH52iFbnkVd0+6bygzgOhf9J+JL+XBnbWkRVt4lCvt6g==
dependencies:
"@types/jest" "*"
"@types/jest-specific-snapshot@^0.5.3":
version "0.5.4"
resolved "https://registry.npmjs.org/@types/jest-specific-snapshot/-/jest-specific-snapshot-0.5.4.tgz#997364c39a59ddeff0ee790a19415e79dd061d1e"
@ -3777,6 +3831,14 @@
"@webassemblyjs/wast-parser" "1.9.0"
"@xtuc/long" "4.2.2"
"@wordpress/jest-puppeteer-axe@^1.5.0":
version "1.8.0"
resolved "https://registry.npmjs.org/@wordpress/jest-puppeteer-axe/-/jest-puppeteer-axe-1.8.0.tgz#6ddcc36d46c253b06029b894e93da43756aa5853"
integrity sha512-k+2+zfpG1ydbjjeXEVCQbLobqpZASssfa1tHVFoHbkhHU6y/0HDuNAKnxIBqD7MswhQ6/NfwV7jSLlwtkSAXLA==
dependencies:
"@babel/runtime" "^7.9.2"
axe-puppeteer "^1.1.0"
"@xstate/fsm@^1.4.0":
version "1.4.0"
resolved "https://registry.npmjs.org/@xstate/fsm/-/fsm-1.4.0.tgz#6fd082336fde4d026e9e448576189ee5265fa51a"
@ -4647,6 +4709,18 @@ aws4@^1.8.0:
resolved "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
axe-core@^3.5.3:
version "3.5.3"
resolved "https://registry.npmjs.org/axe-core/-/axe-core-3.5.3.tgz#5b7c0ee7c5197d546bd3a07c3ef701896f5773e9"
integrity sha512-HZpLE7xu05+8AbpqXITGdxp1Xwk8ysAXrg7MiKRY27py3DAyEJpoJQo1727pWF3F+O79V3r+cTWhOzfB49P89w==
axe-puppeteer@^1.1.0:
version "1.1.0"
resolved "https://registry.npmjs.org/axe-puppeteer/-/axe-puppeteer-1.1.0.tgz#efcf0666a7d8fefec6930b4b6ec3476c403d1b91"
integrity sha512-VS17Y1rDQe6A0PdeTPxwOSBfmOdj6efgxyre9cN1du1snnVilczSDtQsgifBKBlzoL/3DKfGpgIi+N+zrzODOg==
dependencies:
axe-core "^3.5.3"
axios@0.15.3:
version "0.15.3"
resolved "https://registry.npmjs.org/axios/-/axios-0.15.3.tgz#2c9d638b2e191a08ea1d6cc988eadd6ba5bdc053"
@ -5082,7 +5156,7 @@ base64-arraybuffer@0.1.5:
resolved "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8"
integrity sha1-c5JncZI7Whl0etZmqlzUv5xunOg=
base64-js@^1.0.2, base64-js@^1.2.3, base64-js@^1.3.0:
base64-js@^1.0.2, base64-js@^1.3.0:
version "1.3.1"
resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1"
integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==
@ -7234,7 +7308,7 @@ debounce@1.2.0:
resolved "https://registry.npmjs.org/debounce/-/debounce-1.2.0.tgz#44a540abc0ea9943018dc0eaa95cce87f65cd131"
integrity sha512-mYtLl1xfZLi1m4RtQYlZgJUNQjl4ZxVnHzIR8nLLgi4q1YT8o/WM+MK/f8yfcc9s5Ir5zRaPZyZU6xs1Syoocg==
debug@2, debug@2.6.9, debug@^2.1.1, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.8, debug@^2.6.9, debug@~2.6.3:
debug@2, debug@2.6.9, debug@^2.1.1, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.3, debug@^2.6.8, debug@^2.6.9, debug@~2.6.3:
version "2.6.9"
resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
@ -7819,10 +7893,10 @@ dotenv@^6.2.0:
resolved "https://registry.npmjs.org/dotenv/-/dotenv-6.2.0.tgz#941c0410535d942c8becf28d3f357dbd9d476064"
integrity sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w==
dotenv@^8.0.0:
version "8.1.0"
resolved "https://registry.npmjs.org/dotenv/-/dotenv-8.1.0.tgz#d811e178652bfb8a1e593c6dd704ec7e90d85ea2"
integrity sha512-GUE3gqcDCaMltj2++g6bRQ5rBJWtkWTmqmD0fo1RnnMuUqHNCt2oTPeDnS9n6fKYvlhn7AeBkb38lymBtWBQdA==
dotenv@^8.0.0, dotenv@^8.1.0:
version "8.2.0"
resolved "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a"
integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==
downshift@^3.4.8:
version "3.4.8"
@ -8121,7 +8195,7 @@ es5-shim@^4.5.13:
resolved "https://registry.npmjs.org/es5-shim/-/es5-shim-4.5.13.tgz#5d88062de049f8969f83783f4a4884395f21d28b"
integrity sha512-xi6hh6gsvDE0MaW4Vp1lgNEBpVcCXRWfPXj5egDvtgLz4L9MEvNwYEMdJH+JJinWkwa8c3c3o5HduV7dB/e1Hw==
es6-error@4.1.1, es6-error@^4.0.1:
es6-error@4.1.1, es6-error@^4.0.1, es6-error@^4.0.2:
version "4.1.1"
resolved "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d"
integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==
@ -8147,7 +8221,7 @@ es6-map@^0.1.3:
es6-symbol "~3.1.1"
event-emitter "~0.3.5"
es6-promise-pool@^2.5.0:
es6-promise-pool@^2.4.4, es6-promise-pool@^2.5.0:
version "2.5.0"
resolved "https://registry.npmjs.org/es6-promise-pool/-/es6-promise-pool-2.5.0.tgz#147c612b36b47f105027f9d2bf54a598a99d9ccb"
integrity sha1-FHxhKza0fxBQJ/nSv1SlmKmdnMs=
@ -9687,6 +9761,11 @@ get-stdin@^4.0.1:
resolved "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe"
integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=
get-stdin@^5.0.1:
version "5.0.1"
resolved "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398"
integrity sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=
get-stdin@^6.0.0:
version "6.0.0"
resolved "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b"
@ -10000,6 +10079,11 @@ glogg@^1.0.0:
dependencies:
sparkles "^1.0.0"
glur@^1.1.2:
version "1.1.2"
resolved "https://registry.npmjs.org/glur/-/glur-1.1.2.tgz#f20ea36db103bfc292343921f1f91e83c3467689"
integrity sha1-8g6jbbEDv8KSNDkh8fkeg8NGdok=
gonzales-pe@^4.2.4:
version "4.2.4"
resolved "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.2.4.tgz#356ae36a312c46fe0f1026dd6cb539039f8500d2"
@ -11980,6 +12064,20 @@ jest-haste-map@^25.2.6:
optionalDependencies:
fsevents "^2.1.2"
jest-image-snapshot@^2.8.2:
version "2.12.0"
resolved "https://registry.npmjs.org/jest-image-snapshot/-/jest-image-snapshot-2.12.0.tgz#5289438cbdc8f2ed834e798c3503ed7313153df8"
integrity sha512-hRiy+1Ygv1Of0As9R8M2Q8eTawT9wmmezJKAGfeciZrYllQW5bGL0n6Wgk/J2OG70t5zJr3ZXDx2faui1uGw0g==
dependencies:
chalk "^1.1.3"
get-stdin "^5.0.1"
glur "^1.1.2"
lodash "^4.17.4"
mkdirp "^0.5.1"
pixelmatch "^4.0.2"
pngjs "^3.3.3"
rimraf "^2.6.2"
jest-jasmine2@^25.2.7:
version "25.2.7"
resolved "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-25.2.7.tgz#55ff87f8f462ef0e2f16fd19430b8be8bcebef0e"
@ -13752,17 +13850,17 @@ miller-rabin@^4.0.0:
bn.js "^4.0.0"
brorand "^1.0.1"
mime-db@1.40.0, "mime-db@>= 1.40.0 < 2":
version "1.40.0"
resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32"
integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==
mime-db@1.44.0, "mime-db@>= 1.40.0 < 2":
version "1.44.0"
resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92"
integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==
mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24:
version "2.1.24"
resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81"
integrity sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==
mime-types@^2.1.12, mime-types@^2.1.14, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24:
version "2.1.27"
resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f"
integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==
dependencies:
mime-db "1.40.0"
mime-db "1.44.0"
mime@1.6.0:
version "1.6.0"
@ -15603,14 +15701,14 @@ pend@~1.2.0:
resolved "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA=
percy-client@^3.0.3:
version "3.0.5"
resolved "https://registry.npmjs.org/percy-client/-/percy-client-3.0.5.tgz#6210b7aaffe45e18111d5c4d871f97e2e78ca212"
integrity sha512-DF7Ls0CCSnbNUMmaF5SHHPGBTOEEN/RASzol4e5w6QO9anSU9tujFXRW3GFuKwfafyGbGU09Bn96npuBUleLFA==
percy-client@^3.0.0, percy-client@^3.0.3:
version "3.7.0"
resolved "https://registry.npmjs.org/percy-client/-/percy-client-3.7.0.tgz#780e7d780c7f646e59ffb6ee9d3d16e8237851ff"
integrity sha512-5levWR/nfVuSDL9YPN9Sn1M41I2/FmC/FndhD84s6W+mrVC4mB0cc9cT9F58hLuh7/133I/YvyI9Vc6NN41+2g==
dependencies:
base64-js "^1.2.3"
bluebird "^3.5.1"
bluebird-retry "^0.11.0"
dotenv "^8.1.0"
es6-promise-pool "^2.5.0"
jssha "^2.1.0"
regenerator-runtime "^0.13.1"
@ -15692,6 +15790,13 @@ pirates@^4.0.1:
dependencies:
node-modules-regexp "^1.0.0"
pixelmatch@^4.0.2:
version "4.0.2"
resolved "https://registry.npmjs.org/pixelmatch/-/pixelmatch-4.0.2.tgz#8f47dcec5011b477b67db03c243bc1f3085e8854"
integrity sha1-j0fc7FARtHe2fbA8JDvB8wheiFQ=
dependencies:
pngjs "^3.0.0"
pkg-conf@^2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz#2126514ca6f2abfebd168596df18ba57867f0058"
@ -15738,6 +15843,11 @@ pn@^1.1.0:
resolved "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb"
integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==
pngjs@^3.0.0, pngjs@^3.3.3:
version "3.4.0"
resolved "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f"
integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==
pnp-webpack-plugin@1.5.0:
version "1.5.0"
resolved "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.5.0.tgz#62a1cd3068f46d564bb33c56eb250e4d586676eb"
@ -16579,7 +16689,7 @@ puppeteer@2.0.0:
rimraf "^2.6.1"
ws "^6.1.0"
puppeteer@^1.13.0:
puppeteer@^1.13.0, puppeteer@^1.4.0:
version "1.20.0"
resolved "https://registry.npmjs.org/puppeteer/-/puppeteer-1.20.0.tgz#e3d267786f74e1d87cf2d15acc59177f471bbe38"
integrity sha512-bt48RDBy2eIwZPrkgbcwHtb51mj2nKvHOPMaSH2IsWiv7lOG9k9zhaRzpDZafrk05ajMc3cu+lSQYYOfH2DkVQ==
@ -18572,7 +18682,7 @@ slide@^1.1.6, slide@~1.1.3, slide@~1.1.6:
resolved "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707"
integrity sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=
slugify@^1.4.0:
slugify@^1.1.0, slugify@^1.4.0:
version "1.4.0"
resolved "https://registry.npmjs.org/slugify/-/slugify-1.4.0.tgz#c9557c653c54b0c7f7a8e786ef3431add676d2cb"
integrity sha512-FtLNsMGBSRB/0JOE2A0fxlqjI6fJsgHGS13iTuVT28kViI4JjUiNqp/vyis0ZXYcMnpR3fzGNkv+6vRlI2GwdQ==
@ -18803,7 +18913,8 @@ source-map@^0.7.3:
integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==
"sourcegraph@link:packages/sourcegraph-extension-api":
version "24.2.0"
version "0.0.0"
uid ""
space-separated-tokens@^1.0.0:
version "1.1.2"
@ -20799,7 +20910,7 @@ w3c-xmlserializer@^1.1.2:
webidl-conversions "^4.0.2"
xml-name-validator "^3.0.0"
walk@^2.3.14:
walk@^2.3.14, walk@^2.3.9:
version "2.3.14"
resolved "https://registry.npmjs.org/walk/-/walk-2.3.14.tgz#60ec8631cfd23276ae1e7363ce11d626452e1ef3"
integrity sha512-5skcWAUmySj6hkBdH6B6+3ddMjVQYH5Qy9QGbPmN8kVmLteXk+yVXg+yfk1nbX30EYakahLrr8iPcCxJQSCBeg==
@ -21551,7 +21662,7 @@ yargs@^15.3.1:
y18n "^4.0.0"
yargs-parser "^18.1.1"
yargs@^7.1.0:
yargs@^7.0.2, yargs@^7.1.0:
version "7.1.0"
resolved "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8"
integrity sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=