Skip to content

Commit

Permalink
Bug 1497931 - Remove jquery and Bootstrap (#6035)
Browse files Browse the repository at this point in the history
* refactor components using bootstrap elements with reactstrap
* add template for cdn to access Bootstrap CSS
* remove bootstrap, jquery and angular library
* fixes to get tests passing and add bootstrap link to csp
  • Loading branch information
sarah-clements committed Feb 21, 2020
1 parent 2ffc72e commit f83e08b
Show file tree
Hide file tree
Showing 34 changed files with 632 additions and 919 deletions.
9 changes: 9 additions & 0 deletions .neutrinorc.js
Expand Up @@ -16,42 +16,51 @@ module.exports = {
entry: 'job-view/index.jsx',
favicon: 'ui/img/tree_open.png',
title: 'Treeherder',
template: 'ui/index.html',
},
logviewer: {
entry: 'logviewer/index.jsx',
favicon: 'ui/img/logviewerIcon.png',
title: 'Treeherder Logviewer',
template: 'ui/index.html',
},
userguide: {
entry: 'userguide/index.jsx',
favicon: 'ui/img/tree_open.png',
title: 'Treeherder User Guide',
template: 'ui/index.html',
},
login: {
entry: 'login-callback/index.jsx',
title: 'Treeherder Login',
template: 'ui/index.html',
},
testview: {
entry: 'test-view/index.jsx',
title: 'Treeherder Test View',
template: 'ui/index.html',
},
pushhealth: {
entry: 'push-health/index.jsx',
title: 'Push Health',
template: 'ui/index.html',
},
perf: {
entry: 'perfherder/index.jsx',
favicon: 'ui/img/line_chart.png',
title: 'Perfherder',
template: 'ui/index.html',
},
'intermittent-failures': {
entry: 'intermittent-failures/index.jsx',
favicon: 'ui/img/tree_open.png',
title: 'Intermittent Failures View',
template: 'ui/index.html',
},
'taskcluster-auth': {
entry: 'taskcluster-auth-callback/index.jsx',
title: 'Taskcluster Authentication',
template: 'ui/index.html',
},
},
output: '.build/',
Expand Down
3 changes: 0 additions & 3 deletions package.json
Expand Up @@ -23,18 +23,15 @@
"@types/react-dom": "*",
"ajv": "6.10.2",
"auth0-js": "9.11.3",
"bootstrap": "4.3.1",
"fuse.js": "3.4.6",
"history": "4.10.1",
"jquery": "3.4.1",
"js-cookie": "2.2.1",
"js-yaml": "3.13.1",
"json-e": "3.0.1",
"json-schema-defaults": "0.4.0",
"lodash": "4.17.15",
"moment": "2.24.0",
"neutrino": "9.0.0",
"ng-text-truncate-2": "1.0.1",
"numeral": "2.0.6",
"prop-types": "15.7.2",
"query-string": "6.9.0",
Expand Down
11 changes: 11 additions & 0 deletions tests/ui/job-view/Filtering_test.jsx
Expand Up @@ -20,6 +20,17 @@ import {
import jobListFixtureOne from '../mock/job_list/job_1';
import jobMap from '../mock/job_map';

// solution to createRange is not a function error for popper (used by reactstrap)
// https://github.com/mui-org/material-ui/issues/15726#issuecomment-493124813
global.document.createRange = () => ({
setStart: () => {},
setEnd: () => {},
commonAncestorContainer: {
nodeName: 'BODY',
ownerDocument: document,
},
});

describe('Filtering', () => {
const repoName = 'autoland';

Expand Down
15 changes: 13 additions & 2 deletions tests/ui/job-view/PushList_test.jsx
Expand Up @@ -24,6 +24,17 @@ import PushList from '../../../ui/job-view/pushes/PushList';
import { getApiUrl } from '../../../ui/helpers/url';
import { findJobInstance } from '../../../ui/helpers/job';

// solution to createRange is not a function error for popper (used by reactstrap)
// https://github.com/mui-org/material-ui/issues/15726#issuecomment-493124813
global.document.createRange = () => ({
setStart: () => {},
setEnd: () => {},
commonAncestorContainer: {
nodeName: 'BODY',
ownerDocument: document,
},
});

describe('PushList', () => {
const repoName = 'autoland';
const currentRepo = {
Expand Down Expand Up @@ -158,7 +169,7 @@ describe('PushList', () => {
fireEvent.click(actionMenuButton);

const setBottomLink = await waitForElement(() =>
push2.querySelector('.bottom-of-range-menu-item'),
push2.querySelector('[data-testid="bottom-of-range-menu-item"]'),
);

expect(setBottomLink.getAttribute('href')).toContain(
Expand All @@ -184,7 +195,7 @@ describe('PushList', () => {
fireEvent.click(actionMenuButton);

const setTopLink = await waitForElement(() =>
push1.querySelector('.top-of-range-menu-item'),
push1.querySelector('[data-testid="top-of-range-menu-item"]'),
);

expect(setTopLink.getAttribute('href')).toContain(
Expand Down
49 changes: 12 additions & 37 deletions tests/ui/push-health/TestFailure_test.jsx
@@ -1,6 +1,3 @@
import fs from 'fs';
import path from 'path';

import React from 'react';
import fetchMock from 'fetch-mock';
import {
Expand All @@ -17,22 +14,6 @@ import pushHealth from '../mock/push_health';
const repoName = 'autoland';
const crashFailure = pushHealth.metrics.tests.details.needInvestigation[0];
const testFailure = pushHealth.metrics.tests.details.needInvestigation[2];
const cssFile = fs.readFileSync(
path.resolve(
__dirname,
'../../../node_modules/bootstrap/dist/css/bootstrap.css',
),
);

// Need to use this technique to add the CSS to the document since JSDOM doesn't
// load the Reactstrap/Bootstrap CSS.
// Credit: https://stackoverflow.com/questions/52813527/cannot-check-expectelm-not-tobevisible-for-semantic-ui-react-component
const useStyles = container => {
const style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = cssFile;
container.append(style);
};

beforeEach(() => {
fetchMock.get('https://treestatus.mozilla-releng.net/trees/autoland', {
Expand Down Expand Up @@ -77,28 +58,25 @@ describe('TestFailure', () => {
});

test('should not show details by default', async () => {
const { container, getByText } = render(testTestFailure(testFailure));
useStyles(container);

// Must use .toBeVisible() rather than .toBeInTheDocument because
// Collapse just hides elements, doesn't remove them.
expect(
await waitForElement(() =>
getByText('Transactions that explicitly commit ', {
exact: false,
}),
),
).not.toBeVisible();
const { getByText, getByTestId } = render(testTestFailure(testFailure));
const logLineToggle = await waitForElement(() => getByTestId('log-lines'));

// For collapsible components, you must check for 'collapse' (hidden) or 'collapse show' (visible)
// or aria-expanded attribute because collapse just hides elements, doesn't remove them.
expect(logLineToggle).toHaveClass('collapse');
expect(logLineToggle).toHaveAttribute(
'aria-expanded',
expect.stringMatching('false'),
);
expect(
await waitForElement(() => getByText('more...')),
).toBeInTheDocument();
});

test('should show details when click more...', async () => {
const { container, getByText } = render(testTestFailure(testFailure));
const { getByText } = render(testTestFailure(testFailure));
const moreLink = getByText('more...');

useStyles(container);
fireEvent.click(moreLink);

expect(
Expand All @@ -115,12 +93,9 @@ describe('TestFailure', () => {
});

test('should show crash stack and signature when click more...', async () => {
const { container, getByText, getAllByText } = render(
testTestFailure(crashFailure),
);
const { getByText, getAllByText } = render(testTestFailure(crashFailure));
const moreLink = getByText('more...');

useStyles(container);
fireEvent.click(moreLink);

expect(
Expand Down
2 changes: 1 addition & 1 deletion treeherder/middleware.py
Expand Up @@ -15,7 +15,7 @@
"script-src 'self' 'unsafe-eval' 'report-sample'",
# The unsafe-inline is required for react-select's use of emotion (CSS in JS). See bug 1507903.
# The Google entries are required for IFV's use of the Open Sans font from their CDN.
"style-src 'self' 'unsafe-inline' 'report-sample' https://fonts.googleapis.com",
"style-src 'self' 'unsafe-inline' 'report-sample' https://fonts.googleapis.com https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css",
"font-src 'self' https://fonts.gstatic.com",
# The `data:` is required for images that were inlined by webpack's url-loader (as an optimisation).
"img-src 'self' data:",
Expand Down
17 changes: 2 additions & 15 deletions ui/css/treeherder-details-panel.css
Expand Up @@ -106,6 +106,8 @@ div#details-panel-content .details-panel-navbar > ul.tab-headers > li {
.details-panel-navbar .actionbar-nav > li > .btn {
color: #9fa3a5;
padding: 4px 15px;
margin-bottom: 4px;
display: inline-block;
}

div#details-panel-content .actionbar-nav > li > a:hover,
Expand Down Expand Up @@ -186,21 +188,6 @@ div#details-panel-content .actionbar-nav > li > button:focus {
}
}

#actionbar-menu-btn:focus {
box-shadow: none;
border: none;
outline: none;
}

/* Remove the caret from the ellipses */
#actionbar-menu-btn.dropdown-toggle::after {
display: none;
}

#job-details-actionbar #actionbar-menu-btn + ul > li {
padding: 0;
}

/*
* Job details panel (left side)
*/
Expand Down
7 changes: 0 additions & 7 deletions ui/css/treeherder-global.css
Expand Up @@ -89,13 +89,6 @@ input[type='checkbox'] {
cursor: pointer;
}

/* For cases where the base Bootstrap 4 equivalent doesn't
work, due to our special uses.*/
.nav-dropdown-menu-right {
left: auto;
right: 0;
}

.form-control:focus {
border: 1px solid #ced4da;
box-shadow: none;
Expand Down
22 changes: 3 additions & 19 deletions ui/css/treeherder-navbar.css
Expand Up @@ -120,20 +120,6 @@ secondary-nav-bar {
color: lightgrey;
}

.watched-repo-info-btn {
padding-left: 6px;
padding-right: 9px;
border-right: 0;
}

.watched-repo-dropdown-item {
margin: 0 10px;
}

.watched-repo-dropdown-item > a {
white-space: normal;
}

.watched-repo-navbar {
overflow: visible;
flex-direction: row;
Expand Down Expand Up @@ -323,8 +309,8 @@ fieldset[disabled] .btn-unclassified-failures.active {
.btn-view-nav:focus,
.btn-view-nav:active,
.btn-view-nav.active {
background-color: #2c3133;
border-color: #1a1d20;
background-color: #2c3133 !important;
border-color: #1a1d20 !important;
color: white;
}
.btn-view-nav.disabled:hover,
Expand Down Expand Up @@ -395,7 +381,7 @@ fieldset[disabled] .btn-view-nav-closed.active {
}

#notification-dropdown {
min-width: 25em;
max-width: 25em;
max-height: 20em;
overflow-y: scroll;
padding-left: 20px;
Expand All @@ -408,8 +394,6 @@ fieldset[disabled] .btn-view-nav-closed.active {
}

.notification-dropdown-line {
padding-top: 3px;
padding-bottom: 3px;
overflow-x: hidden;
text-overflow: ellipsis;
}
Expand Down
11 changes: 1 addition & 10 deletions ui/css/treeherder-resultsets.css
Expand Up @@ -73,11 +73,7 @@
background-color: transparent;
padding-left: 9px;
padding-right: 10px;
}

.btn-push.btn:focus {
-webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
border: 0;
}

.btn-push:hover {
Expand All @@ -97,11 +93,6 @@ fieldset[disabled] .btn-push:hover {
color: white;
}

th-action-button .btn-push {
padding-left: 6px;
font-size: 14px;
}

.watch-commit-btn:not([data-watch-state='none']) {
border: 1px solid;
border-radius: 3px;
Expand Down
16 changes: 16 additions & 0 deletions ui/index.html
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<!-- we need Bootstrap CSS for reactstrap but this is the only way to obtain it without installing the entire library -->
<link
rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh"
crossorigin="anonymous"
/>
</head>
<body>
<div id="root"></div>
</body>
</html>
1 change: 0 additions & 1 deletion ui/intermittent-failures/index.jsx
@@ -1,6 +1,5 @@
import React from 'react';
import { render } from 'react-dom';
import 'bootstrap/dist/css/bootstrap.min.css';
import 'react-table/react-table.css';

import '../css/treeherder-global.css';
Expand Down

0 comments on commit f83e08b

Please sign in to comment.