Skip to content

Commit

Permalink
Add Lint step to CircleCI (getredash#3642)
Browse files Browse the repository at this point in the history
  • Loading branch information
arikfr authored and harveyrendell committed Nov 14, 2019
1 parent 300a653 commit a51ee14
Show file tree
Hide file tree
Showing 10 changed files with 147 additions and 101 deletions.
20 changes: 18 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ jobs:
path: /tmp/test-results
- store_artifacts:
path: coverage.xml
frontend-lint:
docker:
- image: circleci/node:8
steps:
- checkout
- run: mkdir -p /tmp/test-results/eslint
- run: npm install
- run: npm run lint:ci
- store_test_results:
path: /tmp/test-results
frontend-unit-tests:
docker:
- image: circleci/node:8
Expand All @@ -54,6 +64,7 @@ jobs:
- run: npm install
- run: npm run bundle
- run: npm test
- run: npm run lint
frontend-e2e-tests:
environment:
COMPOSE_FILE: .circleci/docker-compose.cypress.yml
Expand Down Expand Up @@ -105,8 +116,13 @@ workflows:
- python-flake8-tests
- legacy-python-flake8-tests
- backend-unit-tests
- frontend-unit-tests
- frontend-e2e-tests
- frontend-lint
- frontend-unit-tests:
requires:
- frontend-lint
- frontend-e2e-tests:
requires:
- frontend-lint
- build-tarball:
requires:
- backend-unit-tests
Expand Down
24 changes: 8 additions & 16 deletions .codeclimate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,12 @@ plugins:
pep8:
enabled: true
eslint:
enabled: true
channel: "eslint-5"
config:
config: client/.eslintrc.js
checks:
import/no-unresolved:
enabled: false
no-multiple-empty-lines: # TODO: Enable
enabled: false
enabled: false
exclude_patterns:
- "tests/**/*.py"
- "migrations/**/*.py"
- "setup/**/*"
- "bin/**/*"
- "**/node_modules/"
- "client/dist/"
- "**/*.pyc"
- "tests/**/*.py"
- "migrations/**/*.py"
- "setup/**/*"
- "bin/**/*"
- "**/node_modules/"
- "client/dist/"
- "**/*.pyc"
65 changes: 33 additions & 32 deletions client/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
module.exports = {
root: true,
extends: ["airbnb", "plugin:jest/recommended"],
plugins: ["jest", "cypress", "chai-friendly"],
extends: ["airbnb"],
settings: {
"import/resolver": "webpack"
},
parser: "babel-eslint",
env: {
"jest/globals": true,
"cypress/globals": true,
"browser": true,
"node": true
browser: true,
node: true
},
rules: {
// allow debugger during development
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
'no-param-reassign': 0,
'no-mixed-operators': 0,
'no-underscore-dangle': 0,
"no-debugger": process.env.NODE_ENV === "production" ? 2 : 0,
"no-param-reassign": 0,
"no-mixed-operators": 0,
"no-underscore-dangle": 0,
"no-use-before-define": ["error", "nofunc"],
"prefer-destructuring": "off",
"prefer-template": "off",
Expand All @@ -27,38 +24,42 @@ module.exports = {
"no-lonely-if": "off",
"consistent-return": "off",
"no-control-regex": "off",
'no-multiple-empty-lines': 'warn',
"no-multiple-empty-lines": "warn",
"no-script-url": "off", // some <a> tags should have href="javascript:void(0)"
'operator-linebreak': 'off',
'react/destructuring-assignment': 'off',
"operator-linebreak": "off",
"react/destructuring-assignment": "off",
"react/jsx-filename-extension": "off",
'react/jsx-one-expression-per-line': 'off',
"react/jsx-one-expression-per-line": "off",
"react/jsx-uses-react": "error",
"react/jsx-uses-vars": "error",
'react/jsx-wrap-multilines': 'warn',
'react/no-access-state-in-setstate': 'warn',
"react/jsx-wrap-multilines": "warn",
"react/no-access-state-in-setstate": "warn",
"react/prefer-stateless-function": "warn",
"react/forbid-prop-types": "warn",
"react/prop-types": "warn",
"jsx-a11y/anchor-is-valid": "off",
"jsx-a11y/click-events-have-key-events": "off",
"jsx-a11y/label-has-associated-control": ["warn", {
"controlComponents": true
}],
"jsx-a11y/label-has-associated-control": [
"warn",
{
controlComponents: true
}
],
"jsx-a11y/label-has-for": "off",
"jsx-a11y/no-static-element-interactions": "off",
"max-len": ['error', 120, 2, {
ignoreUrls: true,
ignoreComments: false,
ignoreRegExpLiterals: true,
ignoreStrings: true,
ignoreTemplateLiterals: true,
}],
"no-else-return": ["error", {"allowElseIf": true}],
"object-curly-newline": ["error", {"consistent": true}],
// needed for cypress tests
"func-names": "off",
"no-unused-expressions": 0,
"chai-friendly/no-unused-expressions": 2
"max-len": [
"error",
120,
2,
{
ignoreUrls: true,
ignoreComments: false,
ignoreRegExpLiterals: true,
ignoreStrings: true,
ignoreTemplateLiterals: true
}
],
"no-else-return": ["error", { allowElseIf: true }],
"object-curly-newline": ["error", { consistent: true }]
}
};
7 changes: 7 additions & 0 deletions client/app/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
extends: ["plugin:jest/recommended"],
plugins: ["jest"],
env: {
"jest/globals": true,
},
};
12 changes: 12 additions & 0 deletions client/cypress/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module.exports = {
extends: ["plugin:cypress/recommended"],
plugins: ["cypress", "chai-friendly"],
env: {
"cypress/globals": true
},
rules: {
"func-names": ["error", "never"],
"no-unused-expressions": 0,
"chai-friendly/no-unused-expressions": 2
}
};
75 changes: 46 additions & 29 deletions client/cypress/integration/dashboard/dashboard_spec.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
const DRAG_PLACEHOLDER_SELECTOR = '.grid-stack-placeholder';

function createNewDashboardByAPI(name) {
return cy.request('POST', 'api/dashboards', { name })
.then(({ body }) => body);
return cy.request('POST', 'api/dashboards', { name }).then(({ body }) => body);
}

function editDashboard() {
Expand All @@ -26,25 +25,28 @@ function addTextboxByAPI(text, dashId) {
},
};

return cy.request('POST', 'api/widgets', data)
.then(({ body }) => {
const id = Cypress._.get(body, 'id');
assert.isDefined(id, 'Widget api call returns widget id');
return `WidgetId${id}`;
});
return cy.request('POST', 'api/widgets', data).then(({ body }) => {
const id = Cypress._.get(body, 'id');
assert.isDefined(id, 'Widget api call returns widget id');
return `WidgetId${id}`;
});
}

function addQueryByAPI(data, shouldPublish = true) {
const merged = Object.assign({
name: 'Test Query',
query: 'select 1',
data_source_id: 1,
options: {
parameters: [],
const merged = Object.assign(
{
name: 'Test Query',
query: 'select 1',
data_source_id: 1,
options: {
parameters: [],
},
schedule: null,
},
schedule: null,
}, data);
data,
);

// eslint-disable-next-line cypress/no-assigning-return-values
const request = cy.request('POST', '/api/queries', merged);
if (shouldPublish) {
request.then(({ body }) => cy.request('POST', `/api/queries/${body.id}`, { is_draft: false }));
Expand Down Expand Up @@ -109,7 +111,9 @@ describe('Dashboard', () => {
it('creates new dashboard', () => {
cy.visit('/dashboards');
cy.getByTestId('CreateButton').click();
cy.get('li[role="menuitem"]').contains('Dashboard').click();
cy.get('li[role="menuitem"]')
.contains('Dashboard')
.click();

cy.server();
cy.route('POST', 'api/dashboards').as('NewDashboard');
Expand Down Expand Up @@ -193,9 +197,13 @@ describe('Dashboard', () => {
cy.visit(this.dashboardUrl);
cy.getByTestId(elTestId)
.within(() => {
cy.get('.widget-menu-regular').click({ force: true }).within(() => {
cy.get('li a').contains('Remove From Dashboard').click({ force: true });
});
cy.get('.widget-menu-regular')
.click({ force: true })
.within(() => {
cy.get('li a')
.contains('Remove From Dashboard')
.click({ force: true });
});
})
.should('not.exist');
});
Expand Down Expand Up @@ -235,18 +243,27 @@ describe('Dashboard', () => {
it('edits textbox', function () {
addTextboxByAPI('Hello World!', this.dashboardId).then((elTestId) => {
cy.visit(this.dashboardUrl);
cy.getByTestId(elTestId).as('textboxEl')
cy.getByTestId(elTestId)
.as('textboxEl')
.within(() => {
cy.get('.widget-menu-regular').click({ force: true }).within(() => {
cy.get('li a').contains('Edit').click({ force: true });
});
cy.get('.widget-menu-regular')
.click({ force: true })
.within(() => {
cy.get('li a')
.contains('Edit')
.click({ force: true });
});
});

const newContent = '[edited]';
cy.get('edit-text-box').should('exist').within(() => {
cy.get('textarea').clear().type(newContent);
cy.contains('button', 'Save').click();
});
cy.get('edit-text-box')
.should('exist')
.within(() => {
cy.get('textarea')
.clear()
.type(newContent);
cy.contains('button', 'Save').click();
});

cy.get('@textboxEl').should('contain', newContent);
});
Expand All @@ -269,7 +286,7 @@ describe('Dashboard', () => {

describe('Draggable', () => {
describe('Grid snap', () => {
beforeEach(function () {
beforeEach(() => {
editDashboard();
});

Expand Down
4 changes: 2 additions & 2 deletions client/cypress/integration/user/login_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ describe('Login', () => {
it('greets the user and take a screenshot', () => {
cy.contains('h3', 'Login to Redash');

cy.wait(1000);
cy.wait(1000); // eslint-disable-line cypress/no-unnecessary-waiting
cy.percySnapshot('Login');
});

Expand All @@ -24,7 +24,7 @@ describe('Login', () => {
cy.title().should('eq', 'Redash');
cy.contains('Example Admin');

cy.wait(1000);
cy.wait(1000); // eslint-disable-line cypress/no-unnecessary-waiting
cy.percySnapshot('Homepage');
});
});
2 changes: 1 addition & 1 deletion client/cypress/support/commands.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import '@percy/cypress'; // eslint-disable-line import/no-extraneous-dependencies
import '@percy/cypress'; // eslint-disable-line import/no-extraneous-dependencies, import/no-unresolved

Cypress.Commands.add('login', (email = 'admin@redash.io', password = 'password') => cy.request({
url: '/login',
Expand Down
Loading

0 comments on commit a51ee14

Please sign in to comment.