feat: bundle assets with content (#2958)

* fix(media_folder_relative): use collection name in unpublished entry

* refactor: pass arguments as object to AssetProxy ctor

* feat: support media folders per collection

* feat: resolve media files path based on entry path

* fix: asset public path resolving

* refactor: introduce typescript for AssetProxy

* refactor: code cleanup

* refactor(asset-proxy): add tests,switch to typescript,extract arguments

* refactor: typescript for editorialWorkflow

* refactor: add typescript for media library actions

* refactor: fix type error on map set

* refactor: move locale selector into reducer

* refactor: add typescript for entries actions

* refactor: remove duplication between asset store and media lib

* feat: load assets from backend using API

* refactor(github): add typescript, cache media files

* fix: don't load media URL if already loaded

* feat: add media folder config to collection

* fix: load assets from API when not in UI state

* feat: load entry media files when opening media library

* fix: editorial workflow draft media files bug fixes

* test(unit): fix unit tests

* fix: editor control losing focus

* style: add eslint object-shorthand rule

* test(cypress): re-record mock data

* fix: fix non github backends, large media

* test: uncomment only in tests

* fix(backend-test): add missing displayURL property

* test(e2e): add media library tests

* test(e2e): enable visual testing

* test(e2e): add github backend media library tests

* test(e2e): add git-gateway large media tests

* chore: post rebase fixes

* test: fix tests

* test: fix tests

* test(cypress): fix tests

* docs: add media_folder docs

* test(e2e): add media library delete test

* test(e2e): try and fix image comparison on CI

* ci: reduce test machines from 9 to 8

* test: add reducers and selectors unit tests

* test(e2e): disable visual regression testing for now

* test: add getAsset unit tests

* refactor: use Asset class component instead of hooks

* build: don't inline source maps

* test: add more media path tests
This commit is contained in:
Erez Rokah 2019-12-18 18:16:02 +02:00 committed by Shawn Erquhart
parent 7e4d4c1cc4
commit 2b41d8a838
231 changed files with 37961 additions and 18373 deletions

View File

@ -28,6 +28,8 @@ module.exports = {
'emotion/no-vanilla': 'error',
'emotion/import-from-emotion': 'error',
'emotion/styled-import': 'error',
'require-atomic-updates': [0],
'object-shorthand': ['error', 'always'],
},
plugins: ['babel', 'emotion', 'cypress'],
settings: {
@ -35,4 +37,35 @@ module.exports = {
version: 'detect',
},
},
overrides: [
{
files: ['*.ts', '*.tsx'],
parser: '@typescript-eslint/parser',
extends: [
'eslint:recommended',
'plugin:react/recommended',
'plugin:cypress/recommended',
'plugin:@typescript-eslint/recommended',
'prettier/@typescript-eslint',
'plugin:import/errors',
'plugin:import/warnings',
'plugin:import/typescript',
],
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
ecmaFeatures: {
jsx: true,
},
},
rules: {
'require-atomic-updates': [0],
'@typescript-eslint/explicit-function-return-type': 0,
'@typescript-eslint/no-use-before-define': [
'error',
{ functions: false, classes: true, variables: true },
],
},
},
],
};

View File

@ -47,7 +47,7 @@ jobs:
name: dev-test-website-node-${{ matrix.node-version }}
path: dev-test
# non forked workflow (has acceess to build secrets)
# non forked workflow (has access to build secrets)
e2e-with-cypress-record:
needs: build
if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false)
@ -55,7 +55,7 @@ jobs:
strategy:
matrix:
machine: [1, 2, 3, 4, 5]
machine: [1, 2, 3, 4, 5, 6, 7, 8]
steps:
- uses: actions/checkout@v1
@ -85,7 +85,7 @@ jobs:
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
NODE_OPTIONS: --max-old-space-size=4096
# forked workflow (no acceess to build secrets)
# forked workflow (no access to build secrets)
e2e-no-cypress-record:
needs: build
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true

1
.gitignore vendored
View File

@ -12,6 +12,7 @@ manifest.yml
website/data/contributors.json
cypress/videos
cypress/screenshots
__diff_output__
/coverage/
.cache
*.log

View File

@ -50,6 +50,7 @@ const defaultPlugins = [
localforage: 'localforage',
redux: 'redux',
},
extensions: ['.js', '.jsx', '.es', '.es6', '.mjs', '.ts', '.tsx'],
}
: {
root: path.join(__dirname, 'packages/netlify-cms-core/src/components'),
@ -68,6 +69,7 @@ const defaultPlugins = [
localforage: 'localforage',
redux: 'redux',
},
extensions: ['.js', '.jsx', '.es', '.es6', '.mjs', '.ts', '.tsx'],
},
],
];
@ -82,6 +84,7 @@ const presets = () => {
autoLabel: true,
},
],
'@babel/typescript',
];
};

View File

@ -1,4 +0,0 @@
const babelJest = require('babel-jest');
const babelConfig = require('./babel.config.js');
module.exports = babelJest.createTransformer(babelConfig);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -1,21 +1,19 @@
const backend = 'github';
export const before = (taskResult, options) => {
Cypress.config('taskTimeout', 5 * 60 * 1000);
export const before = (taskResult, options, backend = 'github') => {
Cypress.config('taskTimeout', 7 * 60 * 1000);
cy.task('setupBackend', { backend, options }).then(data => {
taskResult.data = data;
Cypress.config('defaultCommandTimeout', data.mockResponses ? 5 * 1000 : 1 * 60 * 1000);
});
};
export const after = taskResult => {
export const after = (taskResult, backend = 'github') => {
cy.task('teardownBackend', {
backend,
...taskResult.data,
});
};
export const beforeEach = taskResult => {
export const beforeEach = (taskResult, backend = 'github') => {
const spec = Cypress.mocha.getRunner().suite.ctx.currentTest.parent.title;
const testName = Cypress.mocha.getRunner().suite.ctx.currentTest.title;
cy.task('setupBackendTest', {
@ -34,7 +32,7 @@ export const beforeEach = taskResult => {
return cy.clock(0, ['Date']);
};
export const afterEach = taskResult => {
export const afterEach = (taskResult, backend = 'github') => {
const spec = Cypress.mocha.getRunner().suite.ctx.currentTest.parent.title;
const testName = Cypress.mocha.getRunner().suite.ctx.currentTest.title;

View File

@ -0,0 +1,169 @@
import path from 'path';
import '../../utils/dismiss-local-backup';
import {
login,
goToMediaLibrary,
newPost,
populateEntry,
exitEditor,
goToWorkflow,
updateWorkflowStatus,
publishWorkflowEntry,
goToEntry,
goToCollections,
} from '../../utils/steps';
import { workflowStatus } from '../../utils/constants';
function uploadMediaFile() {
assertNoImagesInLibrary();
const fixture = 'media/netlify.png';
cy.fixture(fixture).then(fileContent => {
cy.get('input[type="file"]').upload({
fileContent,
fileName: path.basename(fixture),
mimeType: 'image/png',
});
});
cy.contains('span', 'Uploading...').should('not.exist');
assertImagesInLibrary();
}
function assertImagesInLibrary() {
cy.get('img[class*="CardImage"]').should('exist');
}
function assertNoImagesInLibrary() {
cy.get('img[class*="CardImage"]').should('not.exist');
}
function deleteImage() {
cy.get('img[class*="CardImage"]').click();
cy.contains('button', 'Delete selected').click();
assertNoImagesInLibrary();
}
function chooseSelectedMediaFile() {
cy.contains('button', 'Choose selected').click();
}
function chooseAnImage() {
cy.contains('button', 'Choose an image').click();
}
function waitForEntryToLoad() {
cy.contains('div', 'Loading entry...').should('not.exist');
}
function matchImageSnapshot() {
// cy.matchImageSnapshot();
}
function newPostAndUploadImage() {
newPost();
chooseAnImage();
uploadMediaFile();
}
function newPostWithImage(entry) {
newPostAndUploadImage();
chooseSelectedMediaFile();
populateEntry(entry);
waitForEntryToLoad();
}
function publishPostWithImage(entry) {
newPostWithImage(entry);
exitEditor();
goToWorkflow();
updateWorkflowStatus(entry, workflowStatus.draft, workflowStatus.ready);
publishWorkflowEntry(entry);
}
function closeMediaLibrary() {
cy.get('button[class*="CloseButton"]').click();
}
function switchToGridView() {
cy.get('div[class*="ViewControls"]').within(() => {
cy.get('button')
.last()
.click();
});
}
function assertGridEntryImage(entry) {
cy.contains('li', entry.title).within(() => {
cy.get('div[class*="CardImage"]').should('be.visible');
});
}
export default function({ entries, getUser }) {
beforeEach(() => {
login(getUser && getUser());
});
it('can upload image from global media library', () => {
goToMediaLibrary();
uploadMediaFile();
matchImageSnapshot();
closeMediaLibrary();
});
it('can delete image from global media library', () => {
goToMediaLibrary();
uploadMediaFile();
closeMediaLibrary();
goToMediaLibrary();
deleteImage();
matchImageSnapshot();
closeMediaLibrary();
});
it('can upload image from entry media library', () => {
newPostAndUploadImage();
matchImageSnapshot();
closeMediaLibrary();
exitEditor();
});
it('can save entry with image', () => {
newPostWithImage(entries[0]);
matchImageSnapshot();
exitEditor();
});
it('can publish entry with image', () => {
publishPostWithImage(entries[0]);
goToEntry(entries[0]);
waitForEntryToLoad();
matchImageSnapshot();
});
it('should not show draft entry image in global media library', () => {
newPostWithImage(entries[0]);
exitEditor();
goToMediaLibrary();
assertNoImagesInLibrary();
matchImageSnapshot();
});
it('should show published entry image in global media library', () => {
publishPostWithImage(entries[0]);
cy.clock().tick();
goToMediaLibrary();
assertImagesInLibrary();
matchImageSnapshot();
});
it('should show published entry image in grid view', () => {
publishPostWithImage(entries[0]);
goToCollections();
switchToGridView();
assertGridEntryImage(entries[0]);
matchImageSnapshot();
});
}

View File

@ -0,0 +1,27 @@
import fixture from './media/media_library';
import { entry1 } from './github/entries';
import * as specUtils from './github/spec_utils';
const backend = 'git-gateway';
describe('Git Gateway Backend Media Library - Large Media', () => {
let taskResult = { data: {} };
before(() => {
specUtils.before(taskResult, {}, backend);
});
after(() => {
specUtils.after(taskResult, backend);
});
beforeEach(() => {
specUtils.beforeEach(taskResult, backend);
});
afterEach(() => {
specUtils.afterEach(taskResult, backend);
});
fixture({ entries: [entry1], getUser: () => taskResult.data.user });
});

View File

@ -0,0 +1,25 @@
import fixture from './media/media_library';
import { entry1 } from './github/entries';
import * as specUtils from './github/spec_utils';
describe('GitHub Backend Media Library - GraphQL API', () => {
let taskResult = { data: {} };
before(() => {
specUtils.before(taskResult, { use_graphql: true });
});
after(() => {
specUtils.after(taskResult);
});
beforeEach(() => {
specUtils.beforeEach(taskResult);
});
afterEach(() => {
specUtils.afterEach(taskResult);
});
fixture({ entries: [entry1], getUser: () => taskResult.data.user });
});

View File

@ -0,0 +1,25 @@
import fixture from './media/media_library';
import { entry1 } from './github/entries';
import * as specUtils from './github/spec_utils';
describe('GitHub Backend Media Library - REST API', () => {
let taskResult = { data: {} };
before(() => {
specUtils.before(taskResult, { use_graphql: false });
});
after(() => {
specUtils.after(taskResult);
});
beforeEach(() => {
specUtils.beforeEach(taskResult);
});
afterEach(() => {
specUtils.afterEach(taskResult);
});
fixture({ entries: [entry1], getUser: () => taskResult.data.user });
});

View File

@ -0,0 +1,21 @@
import fixture from './media/media_library';
const entries = [
{
title: 'first title',
body: 'first body',
},
];
describe('Test Backend Media Library', () => {
after(() => {
cy.task('teardownBackend', { backend: 'test' });
});
before(() => {
Cypress.config('defaultCommandTimeout', 4000);
cy.task('setupBackend', { backend: 'test' });
});
fixture({ entries });
});

View File

@ -0,0 +1,250 @@
const fetch = require('node-fetch');
const {
getGitClient,
transformRecordedData,
setupGitHub,
teardownGitHub,
setupGitHubTest,
teardownGitHubTest,
} = require('./github');
function getEnvs() {
const {
NETLIFY_API_TOKEN: netlifyApiToken,
GITHUB_REPO_TOKEN: githubToken,
NETLIFY_INSTALLATION_ID: installationId,
} = process.env;
if (!netlifyApiToken) {
throw new Error(
'Please set NETLIFY_API_TOKEN, GITHUB_REPO_TOKEN, NETLIFY_INSTALLATION_ID environment variables',
);
}
return { netlifyApiToken, githubToken, installationId };
}
const apiRoot = 'https://api.netlify.com/api/v1/';
async function get(netlifyApiToken, path) {
const response = await fetch(`${apiRoot}${path}`, {
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${netlifyApiToken}`,
},
}).then(res => res.json());
return response;
}
async function post(netlifyApiToken, path, payload) {
const response = await fetch(`${apiRoot}${path}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${netlifyApiToken}`,
},
body: JSON.stringify(payload),
}).then(res => res.json());
return response;
}
async function del(netlifyApiToken, path) {
const response = await fetch(`${apiRoot}${path}`, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${netlifyApiToken}`,
},
}).then(res => res.text());
return response;
}
async function createSite(netlifyApiToken, payload) {
return post(netlifyApiToken, 'sites', payload);
}
async function enableIdentity(netlifyApiToken, siteId) {
return post(netlifyApiToken, `sites/${siteId}/identity`, {});
}
async function enableGitGateway(netlifyApiToken, siteId, githubToken, repo) {
return post(netlifyApiToken, `sites/${siteId}/services/git/instances`, {
github: {
repo,
access_token: githubToken,
},
});
}
async function enableLargeMedia(netlifyApiToken, siteId) {
return post(netlifyApiToken, `sites/${siteId}/services/large-media/instances`, {});
}
async function waitForDeploys(netlifyApiToken, siteId) {
for (let i = 0; i < 10; i++) {
const deploys = await get(netlifyApiToken, `sites/${siteId}/deploys`);
if (deploys.some(deploy => deploy.state === 'ready')) {
console.log('Deploy finished for site:', siteId);
return;
}
console.log('Waiting on deploy of site:', siteId);
await new Promise(resolve => setTimeout(resolve, 30 * 1000));
}
console.log('Timed out waiting on deploy of site:', siteId);
}
async function createUser(netlifyApiToken, siteUrl, email, password) {
const response = await fetch(`${siteUrl}/.netlify/functions/create-user`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${netlifyApiToken}`,
},
body: JSON.stringify({ email, password }),
});
if (response.ok) {
console.log('User created successfully');
} else {
throw new Error('Failed to create user');
}
}
const netlifySiteURL = 'https://fake-site-url.netlify.com/';
const email = 'netlifyCMS@netlify.com';
const password = '12345678';
const backendName = 'git-gateway';
async function setupGitGateway(options) {
const result = await setupGitHub(options);
if (process.env.RECORD_FIXTURES) {
const { netlifyApiToken, githubToken, installationId } = getEnvs();
console.log('Creating Netlify Site');
const { site_id, ssl_url } = await createSite(netlifyApiToken, {
repo: {
provider: 'github',
installation_id: installationId,
repo: `${result.owner}/${result.repo}`,
},
});
console.log('Enabling identity for site:', site_id);
await enableIdentity(netlifyApiToken, site_id);
console.log('Enabling git gateway for site:', site_id);
await enableGitGateway(netlifyApiToken, site_id, githubToken, `${result.owner}/${result.repo}`);
console.log('Enabling large media for site:', site_id);
await enableLargeMedia(netlifyApiToken, site_id);
const git = getGitClient(result.tempDir);
await git.raw([
'config',
'-f',
'.lfsconfig',
'lfs.url',
`https://${site_id}.netlify.com/.netlify/large-media`,
]);
await git.addConfig('commit.gpgsign', 'false');
await git.add('.lfsconfig');
await git.commit('add .lfsconfig');
await git.push('origin', 'master');
await waitForDeploys(netlifyApiToken, site_id);
console.log('Creating user for site:', site_id, 'with email:', email);
try {
await createUser(netlifyApiToken, ssl_url, email, password);
} catch (e) {
console.log(e);
}
return {
...result,
user: {
...result.user,
backendName,
netlifySiteURL: ssl_url,
email,
password,
},
site_id,
ssl_url,
};
} else {
return {
...result,
user: {
...result.user,
backendName,
netlifySiteURL,
email,
password,
},
};
}
}
async function teardownGitGateway(taskData) {
if (process.env.RECORD_FIXTURES) {
const { netlifyApiToken } = getEnvs();
const { site_id } = taskData;
console.log('Deleting Netlify site:', site_id);
await del(netlifyApiToken, `sites/${site_id}`);
const result = await teardownGitHub(taskData);
return result;
}
return null;
}
async function setupGitGatewayTest(taskData) {
if (process.env.RECORD_FIXTURES) {
const result = await setupGitHubTest(taskData);
return result;
}
return null;
}
async function teardownGitGatewayTest(taskData) {
if (process.env.RECORD_FIXTURES) {
const options = {
transformRecordedData: (expectation, toSanitize) => {
const result = transformRecordedData(expectation, toSanitize);
const { httpRequest, httpResponse } = expectation;
if (
httpResponse.body &&
httpResponse.body.string &&
httpRequest.path === '/.netlify/identity/token'
) {
let responseBody = httpResponse.body.string;
const parsed = JSON.parse(responseBody);
parsed.access_token = 'access_token';
parsed.refresh_token = 'refresh_token';
responseBody = JSON.stringify(parsed);
return { ...result, response: responseBody };
} else {
return result;
}
},
};
const result = await teardownGitHubTest(taskData, options);
return result;
}
return null;
}
module.exports = {
setupGitGateway,
teardownGitGateway,
setupGitGatewayTest,
teardownGitGatewayTest,
};

View File

@ -53,6 +53,11 @@ function getEnvs() {
return { owner, repo, token, forkOwner, forkToken };
}
function getGitClient(repoDir) {
const git = simpleGit(repoDir).env({ ...process.env, GIT_SSH_COMMAND, GIT_SSL_NO_VERIFY });
return git;
}
async function prepareTestGitHubRepo() {
const { owner, repo, token } = getEnvs();
@ -71,13 +76,13 @@ async function prepareTestGitHubRepo() {
const tempDir = path.join('.temp', testRepoName);
await fs.remove(tempDir);
let git = simpleGit().env({ ...process.env, GIT_SSH_COMMAND, GIT_SSL_NO_VERIFY });
let git = getGitClient();
const repoUrl = `git@github.com:${owner}/${repo}.git`;
console.log('Cloning repository', repoUrl);
await git.clone(repoUrl, tempDir);
git = simpleGit(tempDir).env({ ...process.env, GIT_SSH_COMMAND, GIT_SSL_NO_VERIFY });
git = getGitClient(tempDir);
console.log('Pushing to new repository', testRepoName);
@ -138,7 +143,7 @@ async function deleteRepositories({ owner, repo, tempDir }) {
}
async function resetOriginRepo({ owner, repo, tempDir }) {
console.log('Resetting origin repo:', `${owner}/repo`);
console.log('Resetting origin repo:', `${owner}/${repo}`);
const { token } = getEnvs();
const client = getGitHubClient(token);
@ -155,6 +160,7 @@ async function resetOriginRepo({ owner, repo, tempDir }) {
owner,
repo,
pull_number,
state: 'closed',
}),
),
);
@ -174,9 +180,9 @@ async function resetOriginRepo({ owner, repo, tempDir }) {
);
console.log('Resetting master');
const git = simpleGit(tempDir).env({ ...process.env, GIT_SSH_COMMAND, GIT_SSL_NO_VERIFY });
const git = getGitClient(tempDir);
await git.push(['--force', 'origin', 'master']);
console.log('Done resetting origin repo:', `${owner}/repo`);
console.log('Done resetting origin repo:', `${owner}/${repo}`);
}
async function resetForkedRepo({ repo }) {
@ -199,7 +205,7 @@ async function resetForkedRepo({ repo }) {
}),
),
);
console.log('Done resetting forked repo:', `${forkOwner}/repo`);
console.log('Done resetting forked repo:', `${forkOwner}/${repo}`);
}
}
@ -306,18 +312,41 @@ const sanitizeString = (
return replaced;
};
const HEADERS_TO_IGNORE = [
'Date',
'X-RateLimit-Remaining',
'X-RateLimit-Reset',
'ETag',
'Last-Modified',
'X-GitHub-Request-Id',
'X-NF-Request-ID',
];
const transformRecordedData = (expectation, toSanitize) => {
const { httpRequest, httpResponse } = expectation;
const responseHeaders = {};
Object.keys(httpResponse.headers).forEach(key => {
responseHeaders[key] = httpResponse.headers[key][0];
});
Object.keys(httpResponse.headers)
.filter(key => !HEADERS_TO_IGNORE.includes(key))
.forEach(key => {
responseHeaders[key] = httpResponse.headers[key][0];
});
let responseBody = null;
if (httpResponse.body && httpResponse.body.string) {
responseBody = httpResponse.body.string;
} else if (
httpResponse.body &&
httpResponse.body.type === 'BINARY' &&
httpResponse.body.base64Bytes
) {
responseBody = {
encoding: 'base64',
content: httpResponse.body.base64Bytes,
};
} else if (httpResponse.body) {
console.log('Unsupported response body:', JSON.stringify(httpResponse.body));
}
// replace recorded user with fake one
@ -345,13 +374,19 @@ const transformRecordedData = (expectation, toSanitize) => {
let body;
if (httpRequest.body && httpRequest.body.string) {
const bodyObject = JSON.parse(httpRequest.body.string);
if (bodyObject.encoding === 'base64') {
// sanitize encoded data
const decodedBody = Buffer.from(bodyObject.content, 'base64').toString();
bodyObject.content = Buffer.from(sanitizeString(decodedBody, toSanitize)).toString('base64');
body = JSON.stringify(bodyObject);
} else {
try {
const bodyObject = JSON.parse(httpRequest.body.string);
if (bodyObject.encoding === 'base64') {
// sanitize encoded data
const decodedBody = Buffer.from(bodyObject.content, 'base64').toString('binary');
const sanitizedContent = sanitizeString(decodedBody, toSanitize);
const sanitizedEncodedContent = Buffer.from(sanitizedContent, 'binary').toString('base64');
bodyObject.content = sanitizedEncodedContent;
body = JSON.stringify(bodyObject);
} else {
body = httpRequest.body.string;
}
} catch (e) {
body = httpRequest.body.string;
}
}
@ -368,7 +403,11 @@ const transformRecordedData = (expectation, toSanitize) => {
return cypressRouteOptions;
};
async function teardownGitHubTest(taskData) {
const defaultOptions = {
transformRecordedData,
};
async function teardownGitHubTest(taskData, { transformRecordedData } = defaultOptions) {
if (process.env.RECORD_FIXTURES) {
await resetRepositories(taskData);
@ -409,6 +448,8 @@ async function teardownGitHubTest(taskData) {
}
module.exports = {
transformRecordedData,
getGitClient,
setupGitHub,
teardownGitHub,
setupGitHubTest,

View File

@ -11,10 +11,18 @@
// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)
require('dotenv').config();
const { addMatchImageSnapshotPlugin } = require('cypress-image-snapshot/plugin');
const { setupGitHub, teardownGitHub, setupGitHubTest, teardownGitHubTest } = require('./github');
const {
setupGitGateway,
teardownGitGateway,
setupGitGatewayTest,
teardownGitGatewayTest,
} = require('./gitGateway');
const { copyBackendFiles } = require('../utils/config');
module.exports = async on => {
module.exports = async (on, config) => {
// `on` is used to hook into various events Cypress emits
on('task', {
async setupBackend({ backend, options }) {
@ -22,8 +30,13 @@ module.exports = async on => {
await copyBackendFiles(backend);
let result = null;
if (backend === 'github') {
result = await setupGitHub(options);
switch (backend) {
case 'github':
result = await setupGitHub(options);
break;
case 'git-gateway':
result = await setupGitGateway(options);
break;
}
return result;
@ -32,8 +45,13 @@ module.exports = async on => {
const { backend } = taskData;
console.log('Tearing down backend', backend);
if (backend === 'github') {
await teardownGitHub(taskData);
switch (backend) {
case 'github':
await teardownGitHub(taskData);
break;
case 'git-gateway':
await teardownGitGateway(taskData);
break;
}
console.log('Restoring defaults');
@ -45,8 +63,13 @@ module.exports = async on => {
const { backend, testName } = taskData;
console.log(`Setting up single test '${testName}' for backend`, backend);
if (backend === 'github') {
await setupGitHubTest(taskData);
switch (backend) {
case 'github':
await setupGitHubTest(taskData);
break;
case 'git-gateway':
await setupGitGatewayTest(taskData);
break;
}
return null;
@ -56,26 +79,42 @@ module.exports = async on => {
console.log(`Tearing down single test '${testName}' for backend`, backend);
if (backend === 'github') {
await teardownGitHubTest(taskData);
switch (backend) {
case 'github':
await teardownGitHubTest(taskData);
break;
case 'git-gateway':
await teardownGitGatewayTest(taskData);
break;
}
return null;
},
});
// to allows usage of a mock proxy
on('before:browser:launch', (browser = {}, args) => {
if (browser.name === 'chrome') {
// to allows usage of a mock proxy
args.push('--ignore-certificate-errors');
return args;
}
if (browser.name === 'electron') {
// to allows usage of a mock proxy
args['ignore-certificate-errors'] = true;
// https://github.com/cypress-io/cypress/issues/2102
if (browser.isHeaded) {
args['width'] = 1200;
args['height'] = 1200;
} else {
args['width'] = 1200;
args['height'] = process.platform === 'darwin' ? 1178 : 1200;
}
return args;
}
});
addMatchImageSnapshotPlugin(on, config);
};

Some files were not shown because too many files have changed in this diff Show More