mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-22 15:37:45 +00:00
Merge branch 'main' of https://github.com/gorogoroumaru/mitmproxy into hover-menu
This commit is contained in:
commit
6824666424
@ -275,6 +275,8 @@ class ClearAll(RequestHandler):
|
|||||||
class ResumeFlows(RequestHandler):
|
class ResumeFlows(RequestHandler):
|
||||||
def post(self):
|
def post(self):
|
||||||
for f in self.view:
|
for f in self.view:
|
||||||
|
if not f.intercepted:
|
||||||
|
continue
|
||||||
f.resume()
|
f.resume()
|
||||||
self.view.update([f])
|
self.view.update([f])
|
||||||
|
|
||||||
|
@ -11,6 +11,13 @@ and activate your virtualenv environment before proceeding.**
|
|||||||
|
|
||||||
- Run `yarn test` to run the test suite.
|
- Run `yarn test` to run the test suite.
|
||||||
|
|
||||||
|
|
||||||
|
## Advanced Tools
|
||||||
|
|
||||||
|
- `yarn run gulp` supports live-reloading if you install a matching
|
||||||
|
[browser extension](http://livereload.com/extensions/).
|
||||||
|
- You can debug application state using the [Redux DevTools](https://github.com/reduxjs/redux-devtools).
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
There are two components:
|
There are two components:
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
.user-select (@val) {
|
.user-select (@val) {
|
||||||
-webkit-touch-callout: @val;
|
-webkit-touch-callout: @val;
|
||||||
-webkit-user-select: @val;
|
-webkit-user-select: @val;
|
||||||
-khtml-user-select: @val;
|
|
||||||
-moz-user-select: @val;
|
-moz-user-select: @val;
|
||||||
-ms-user-select: @val;
|
-ms-user-select: @val;
|
||||||
user-select: @val;
|
user-select: @val;
|
||||||
@ -33,6 +32,7 @@
|
|||||||
&.sort-asc, &.sort-desc {
|
&.sort-asc, &.sort-desc {
|
||||||
background-color: lighten(#F2F2F2, 3%);
|
background-color: lighten(#F2F2F2, 3%);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.sort-asc:after, &.sort-desc:after {
|
&.sort-asc:after, &.sort-desc:after {
|
||||||
font: normal normal normal 14px/1 FontAwesome;
|
font: normal normal normal 14px/1 FontAwesome;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -41,9 +41,11 @@
|
|||||||
padding: 2px;
|
padding: 2px;
|
||||||
background-color: fadeout(lighten(#F2F2F2, 3%), 20%);
|
background-color: fadeout(lighten(#F2F2F2, 3%), 20%);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.sort-asc:after {
|
&.sort-asc:after {
|
||||||
content: "\f0de";
|
content: "\f0de";
|
||||||
}
|
}
|
||||||
|
|
||||||
&.sort-desc:after {
|
&.sort-desc:after {
|
||||||
content: "\f0dd";
|
content: "\f0dd";
|
||||||
}
|
}
|
||||||
@ -53,17 +55,22 @@
|
|||||||
tr {
|
tr {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
|
background-color: white;
|
||||||
|
|
||||||
&:nth-child(even) {
|
&:nth-child(even) {
|
||||||
background-color: rgba(0, 0, 0, 0.05);
|
background-color: #f2f2f2;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.selected {
|
&.selected {
|
||||||
background-color: hsla(209, 52%, 84%, 0.5) !important;
|
background-color: #e0ebf5 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.highlighted {
|
&.highlighted {
|
||||||
background-color: hsla(48, 100%, 50%, 0.4);
|
background-color: #ffeb99;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.highlighted:nth-child(even) {
|
&.highlighted:nth-child(even) {
|
||||||
background-color: hsla(48, 100%, 50%, 0.5);
|
background-color: #ffe57f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,6 +87,7 @@
|
|||||||
color: @interceptorange;
|
color: @interceptorange;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tr.intercepted.has-response {
|
tr.intercepted.has-response {
|
||||||
.col-status, .col-size, .col-time {
|
.col-status, .col-size, .col-time {
|
||||||
color: @interceptorange;
|
color: @interceptorange;
|
||||||
@ -88,6 +96,7 @@
|
|||||||
|
|
||||||
.fa {
|
.fa {
|
||||||
line-height: inherit;
|
line-height: inherit;
|
||||||
|
|
||||||
&.pull-right {
|
&.pull-right {
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
}
|
}
|
||||||
@ -96,39 +105,89 @@
|
|||||||
.col-tls {
|
.col-tls {
|
||||||
width: 10px;
|
width: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.col-tls-https {
|
.col-tls-https {
|
||||||
background-color: rgba(0, 185, 0, 0.5);
|
background-color: rgba(0, 185, 0, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.col-icon {
|
.col-icon {
|
||||||
width: 32px;
|
width: 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.col-path {
|
.col-path {
|
||||||
.fa-repeat {
|
.fa-repeat {
|
||||||
color: green;
|
color: green;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fa-pause {
|
.fa-pause {
|
||||||
color: @interceptorange;
|
color: @interceptorange;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fa-exclamation, .fa-times {
|
.fa-exclamation, .fa-times {
|
||||||
color: darkred;
|
color: darkred;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.col-method {
|
.col-method {
|
||||||
width: 60px;
|
width: 60px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.col-status {
|
.col-status {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.col-size {
|
.col-size {
|
||||||
width: 70px;
|
width: 70px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.col-time {
|
.col-time {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.col-timestamp {
|
.col-timestamp {
|
||||||
width: auto;
|
width: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
td.col-time, td.col-size {
|
td.col-time, td.col-size {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.col-quickactions {
|
||||||
|
width: 0;
|
||||||
|
direction: rtl;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: inherit;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr:hover .col-quickactions {
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-quickactions > div {
|
||||||
|
height: 32px;
|
||||||
|
background-color: inherit;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
div {
|
||||||
|
margin-right: 2px;
|
||||||
|
height: 32px;
|
||||||
|
width: 32px;
|
||||||
|
border-radius: 16px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba(0, 0, 0, 5%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-quickactions .fa-ellipsis-h {
|
||||||
|
transform: translate(-3px, 3px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-quickactions .fa-play {
|
||||||
|
transform: translate(-1px, 2px);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
@import (reference) "../../node_modules/bootstrap/less/mixins/labels.less";
|
@import (reference) "../../node_modules/bootstrap/less/mixins/labels.less";
|
||||||
@import (reference) "../../node_modules/bootstrap/less/labels.less";
|
@import (reference) "../../node_modules/bootstrap/less/labels.less";
|
||||||
|
|
||||||
@menu-height: 85px;
|
@menu-height: 95px;
|
||||||
|
|
||||||
header {
|
header {
|
||||||
padding-top: 6px;
|
padding-top: 6px;
|
||||||
@ -20,17 +20,16 @@ header {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@menu-legend-height: 16px;
|
@menu-legend-height: 16px;
|
||||||
@menu-group-hmargin: 3px;
|
@menu-group-hmargin: 5px;
|
||||||
.menu-group {
|
.menu-group {
|
||||||
margin: 0 @menu-group-hmargin;
|
margin: 0 @menu-group-hmargin 0 (@menu-group-hmargin + 1px);
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
height: @menu-height;
|
height: @menu-height;
|
||||||
vertical-align: top;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-content {
|
.menu-content {
|
||||||
height: @menu-height - @menu-legend-height;
|
height: @menu-height - @menu-legend-height;
|
||||||
text-align: center;
|
display: flow-root;
|
||||||
|
|
||||||
> .btn {
|
> .btn {
|
||||||
height: @menu-height - @menu-legend-height;
|
height: @menu-height - @menu-legend-height;
|
||||||
@ -45,6 +44,16 @@ header {
|
|||||||
margin: 0 auto 5px;
|
margin: 0 auto 5px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
> .btn.btn-sm {
|
||||||
|
height: (@menu-height - @menu-legend-height)/3;
|
||||||
|
padding: 0 5px;
|
||||||
|
i {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 14px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-entry {
|
.menu-entry {
|
||||||
@ -65,6 +74,7 @@ header {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.menu-legend {
|
.menu-legend {
|
||||||
|
color: #777;
|
||||||
height: @menu-legend-height;
|
height: @menu-legend-height;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
@ -73,7 +83,7 @@ header {
|
|||||||
|
|
||||||
.menu-group + .menu-group:before {
|
.menu-group + .menu-group:before {
|
||||||
@space: 10px;
|
@space: 10px;
|
||||||
margin-left: -@menu-group-hmargin;
|
margin-left: -(@menu-group-hmargin + 1px);
|
||||||
content: " ";
|
content: " ";
|
||||||
border-left: solid 1px lighten(grey, 40%);
|
border-left: solid 1px lighten(grey, 40%);
|
||||||
margin-top: @space;
|
margin-top: @space;
|
||||||
@ -82,19 +92,20 @@ header {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@menu-main-gutter-width: 5px;
|
@menu-main-gutter-width: 5px;
|
||||||
.menu-main {
|
.main-menu {
|
||||||
.make-row(@menu-main-gutter-width);
|
display: flex;
|
||||||
padding: 2px 5px;
|
.menu-group {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
.btn-sm {
|
||||||
|
margin-top: 6px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.filter-input {
|
.filter-input {
|
||||||
.make-sm-column(5, @menu-main-gutter-width);
|
margin: 4px 0;
|
||||||
padding: 2.5px;
|
|
||||||
|
|
||||||
@media (max-width: @screen-xs-max) {
|
@media (max-width: @screen-xs-max) {
|
||||||
|
|
||||||
padding: 2px 2.5px;
|
|
||||||
|
|
||||||
> .form-control, > .input-group-addon, > .input-group-btn > .btn {
|
> .form-control, > .input-group-addon, > .input-group-btn > .btn {
|
||||||
height: 23.5px;
|
height: 23.5px;
|
||||||
padding: 1px 5px;
|
padding: 1px 5px;
|
||||||
|
@ -4,12 +4,12 @@ exports[`ShowFullContentButton Component should connect to state 1`] = `null`;
|
|||||||
|
|
||||||
exports[`ShowFullContentButton Component should render correctly 1`] = `
|
exports[`ShowFullContentButton Component should render correctly 1`] = `
|
||||||
<div>
|
<div>
|
||||||
<div
|
<button
|
||||||
className="view-all-content-btn btn-xs btn btn-default"
|
className="view-all-content-btn btn-xs btn btn-default"
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
>
|
>
|
||||||
Show full content
|
Show full content
|
||||||
</div>
|
</button>
|
||||||
<span
|
<span
|
||||||
className="pull-right"
|
className="pull-right"
|
||||||
>
|
>
|
||||||
|
@ -1,116 +1,135 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import renderer from 'react-test-renderer'
|
import renderer from 'react-test-renderer'
|
||||||
import * as Columns from '../../../components/FlowTable/FlowColumns'
|
import {
|
||||||
import { TFlow } from '../../ducks/tutils'
|
IconColumn,
|
||||||
|
MethodColumn,
|
||||||
|
PathColumn,
|
||||||
|
QuickActionsColumn,
|
||||||
|
SizeColumn,
|
||||||
|
StatusColumn,
|
||||||
|
TimeColumn,
|
||||||
|
TimeStampColumn,
|
||||||
|
TLSColumn
|
||||||
|
} from '../../../components/FlowTable/FlowColumns'
|
||||||
|
import {TFlow, TStore} from '../../ducks/tutils'
|
||||||
|
import {Provider} from 'react-redux'
|
||||||
|
|
||||||
describe('FlowColumns Components', () => {
|
describe('Flowcolumns Components', () => {
|
||||||
|
|
||||||
let tflow = TFlow()
|
let tflow = TFlow()
|
||||||
it('should render TLSColumn', () => {
|
it('should render TLSColumn', () => {
|
||||||
let tlsColumn = renderer.create(<Columns.TLSColumn flow={tflow}/>),
|
let tlsColumn = renderer.create(<TLSColumn flow={tflow}/>),
|
||||||
tree = tlsColumn.toJSON()
|
tree = tlsColumn.toJSON()
|
||||||
expect(tree).toMatchSnapshot()
|
expect(tree).toMatchSnapshot()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should render IconColumn', () => {
|
it('should render IconColumn', () => {
|
||||||
let iconColumn = renderer.create(<Columns.IconColumn flow={tflow}/>),
|
let iconColumn = renderer.create(<IconColumn flow={tflow}/>),
|
||||||
tree = iconColumn.toJSON()
|
tree = iconColumn.toJSON()
|
||||||
// plain
|
// plain
|
||||||
expect(tree).toMatchSnapshot()
|
expect(tree).toMatchSnapshot()
|
||||||
// not modified
|
// not modified
|
||||||
tflow.response.status_code = 304
|
tflow.response.status_code = 304
|
||||||
iconColumn = renderer.create(<Columns.IconColumn flow={tflow}/>)
|
iconColumn = renderer.create(<IconColumn flow={tflow}/>)
|
||||||
tree = iconColumn.toJSON()
|
tree = iconColumn.toJSON()
|
||||||
expect(tree).toMatchSnapshot()
|
expect(tree).toMatchSnapshot()
|
||||||
// redirect
|
// redirect
|
||||||
tflow.response.status_code = 302
|
tflow.response.status_code = 302
|
||||||
iconColumn = renderer.create(<Columns.IconColumn flow={tflow}/>)
|
iconColumn = renderer.create(<IconColumn flow={tflow}/>)
|
||||||
tree = iconColumn.toJSON()
|
tree = iconColumn.toJSON()
|
||||||
expect(tree).toMatchSnapshot()
|
expect(tree).toMatchSnapshot()
|
||||||
// image
|
// image
|
||||||
let imageFlow = TFlow()
|
let imageFlow = TFlow()
|
||||||
imageFlow.response.headers = [['Content-Type', 'image/jpeg']]
|
imageFlow.response.headers = [['Content-Type', 'image/jpeg']]
|
||||||
iconColumn = renderer.create(<Columns.IconColumn flow={imageFlow}/>)
|
iconColumn = renderer.create(<IconColumn flow={imageFlow}/>)
|
||||||
tree = iconColumn.toJSON()
|
tree = iconColumn.toJSON()
|
||||||
expect(tree).toMatchSnapshot()
|
expect(tree).toMatchSnapshot()
|
||||||
// javascript
|
// javascript
|
||||||
let jsFlow = TFlow()
|
let jsFlow = TFlow()
|
||||||
jsFlow.response.headers = [['Content-Type', 'application/x-javascript']]
|
jsFlow.response.headers = [['Content-Type', 'application/x-javascript']]
|
||||||
iconColumn = renderer.create(<Columns.IconColumn flow={jsFlow}/>)
|
iconColumn = renderer.create(<IconColumn flow={jsFlow}/>)
|
||||||
tree = iconColumn.toJSON()
|
tree = iconColumn.toJSON()
|
||||||
expect(tree).toMatchSnapshot()
|
expect(tree).toMatchSnapshot()
|
||||||
// css
|
// css
|
||||||
let cssFlow = TFlow()
|
let cssFlow = TFlow()
|
||||||
cssFlow.response.headers = [['Content-Type', 'text/css']]
|
cssFlow.response.headers = [['Content-Type', 'text/css']]
|
||||||
iconColumn = renderer.create(<Columns.IconColumn flow={cssFlow}/>)
|
iconColumn = renderer.create(<IconColumn flow={cssFlow}/>)
|
||||||
tree = iconColumn.toJSON()
|
tree = iconColumn.toJSON()
|
||||||
expect(tree).toMatchSnapshot()
|
expect(tree).toMatchSnapshot()
|
||||||
// html
|
// html
|
||||||
let htmlFlow = TFlow()
|
let htmlFlow = TFlow()
|
||||||
htmlFlow.response.headers = [['Content-Type', 'text/html']]
|
htmlFlow.response.headers = [['Content-Type', 'text/html']]
|
||||||
iconColumn = renderer.create(<Columns.IconColumn flow={htmlFlow}/>)
|
iconColumn = renderer.create(<IconColumn flow={htmlFlow}/>)
|
||||||
tree = iconColumn.toJSON()
|
tree = iconColumn.toJSON()
|
||||||
expect(tree).toMatchSnapshot()
|
expect(tree).toMatchSnapshot()
|
||||||
// default
|
// default
|
||||||
let fooFlow = TFlow()
|
let fooFlow = TFlow()
|
||||||
fooFlow.response.headers = [['Content-Type', 'foo']]
|
fooFlow.response.headers = [['Content-Type', 'foo']]
|
||||||
iconColumn = renderer.create(<Columns.IconColumn flow={fooFlow}/>)
|
iconColumn = renderer.create(<IconColumn flow={fooFlow}/>)
|
||||||
tree = iconColumn.toJSON()
|
tree = iconColumn.toJSON()
|
||||||
expect(tree).toMatchSnapshot()
|
expect(tree).toMatchSnapshot()
|
||||||
// no response
|
// no response
|
||||||
tflow.response = null
|
tflow.response = null
|
||||||
iconColumn = renderer.create(<Columns.IconColumn flow={tflow}/>)
|
iconColumn = renderer.create(<IconColumn flow={tflow}/>)
|
||||||
tree = iconColumn.toJSON()
|
tree = iconColumn.toJSON()
|
||||||
expect(tree).toMatchSnapshot()
|
expect(tree).toMatchSnapshot()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should render pathColumn', () => {
|
it('should render pathColumn', () => {
|
||||||
let pathColumn = renderer.create(<Columns.PathColumn flow={tflow}/>),
|
let pathColumn = renderer.create(<PathColumn flow={tflow}/>),
|
||||||
tree = pathColumn.toJSON()
|
tree = pathColumn.toJSON()
|
||||||
expect(tree).toMatchSnapshot()
|
expect(tree).toMatchSnapshot()
|
||||||
|
|
||||||
tflow.error.msg = 'Connection killed.'
|
tflow.error.msg = 'Connection killed.'
|
||||||
tflow.intercepted = true
|
tflow.intercepted = true
|
||||||
pathColumn = renderer.create(<Columns.PathColumn flow={tflow}/>)
|
pathColumn = renderer.create(<PathColumn flow={tflow}/>)
|
||||||
tree = pathColumn.toJSON()
|
tree = pathColumn.toJSON()
|
||||||
expect(tree).toMatchSnapshot()
|
expect(tree).toMatchSnapshot()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should render MethodColumn', () => {
|
it('should render MethodColumn', () => {
|
||||||
let methodColumn =renderer.create(<Columns.MethodColumn flow={tflow}/>),
|
let methodColumn = renderer.create(<MethodColumn flow={tflow}/>),
|
||||||
tree = methodColumn.toJSON()
|
tree = methodColumn.toJSON()
|
||||||
expect(tree).toMatchSnapshot()
|
expect(tree).toMatchSnapshot()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should render StatusColumn', () => {
|
it('should render StatusColumn', () => {
|
||||||
let statusColumn = renderer.create(<Columns.StatusColumn flow={tflow}/>),
|
let statusColumn = renderer.create(<StatusColumn flow={tflow}/>),
|
||||||
tree = statusColumn.toJSON()
|
tree = statusColumn.toJSON()
|
||||||
expect(tree).toMatchSnapshot()
|
expect(tree).toMatchSnapshot()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should render SizeColumn', () => {
|
it('should render SizeColumn', () => {
|
||||||
tflow = TFlow()
|
tflow = TFlow()
|
||||||
let sizeColumn = renderer.create(<Columns.SizeColumn flow={tflow}/>),
|
let sizeColumn = renderer.create(<SizeColumn flow={tflow}/>),
|
||||||
tree = sizeColumn.toJSON()
|
tree = sizeColumn.toJSON()
|
||||||
expect(tree).toMatchSnapshot()
|
expect(tree).toMatchSnapshot()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should render TimeColumn', () => {
|
it('should render TimeColumn', () => {
|
||||||
let timeColumn = renderer.create(<Columns.TimeColumn flow={tflow}/>),
|
let timeColumn = renderer.create(<TimeColumn flow={tflow}/>),
|
||||||
tree = timeColumn.toJSON()
|
tree = timeColumn.toJSON()
|
||||||
expect(tree).toMatchSnapshot()
|
expect(tree).toMatchSnapshot()
|
||||||
|
|
||||||
tflow.response = null
|
tflow.response = null
|
||||||
timeColumn = renderer.create(<Columns.TimeColumn flow={tflow}/>),
|
timeColumn = renderer.create(<TimeColumn flow={tflow}/>)
|
||||||
tree = timeColumn.toJSON()
|
tree = timeColumn.toJSON()
|
||||||
expect(tree).toMatchSnapshot()
|
expect(tree).toMatchSnapshot()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should render TimeStampColumn', () => {
|
it('should render TimeStampColumn', () => {
|
||||||
let timeStampColumn = renderer.create(<Columns.TimeStampColumn flow={tflow}/>),
|
let timeStampColumn = renderer.create(<TimeStampColumn flow={tflow}/>),
|
||||||
tree = timeStampColumn.toJSON()
|
tree = timeStampColumn.toJSON()
|
||||||
tflow.request.timestamp_start =
|
expect(tree).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should render QuickActionsColumn', () => {
|
||||||
|
let store = TStore(),
|
||||||
|
provider = renderer.create(
|
||||||
|
<Provider store={store}>
|
||||||
|
<QuickActionsColumn flow={tflow}/>
|
||||||
|
</Provider>),
|
||||||
|
tree = provider.toJSON()
|
||||||
expect(tree).toMatchSnapshot()
|
expect(tree).toMatchSnapshot()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`FlowColumns Components should render IconColumn 1`] = `
|
exports[`Flowcolumns Components should render IconColumn 1`] = `
|
||||||
<td
|
<td
|
||||||
className="col-icon"
|
className="col-icon"
|
||||||
>
|
>
|
||||||
@ -10,7 +10,7 @@ exports[`FlowColumns Components should render IconColumn 1`] = `
|
|||||||
</td>
|
</td>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`FlowColumns Components should render IconColumn 2`] = `
|
exports[`Flowcolumns Components should render IconColumn 2`] = `
|
||||||
<td
|
<td
|
||||||
className="col-icon"
|
className="col-icon"
|
||||||
>
|
>
|
||||||
@ -20,7 +20,7 @@ exports[`FlowColumns Components should render IconColumn 2`] = `
|
|||||||
</td>
|
</td>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`FlowColumns Components should render IconColumn 3`] = `
|
exports[`Flowcolumns Components should render IconColumn 3`] = `
|
||||||
<td
|
<td
|
||||||
className="col-icon"
|
className="col-icon"
|
||||||
>
|
>
|
||||||
@ -30,7 +30,7 @@ exports[`FlowColumns Components should render IconColumn 3`] = `
|
|||||||
</td>
|
</td>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`FlowColumns Components should render IconColumn 4`] = `
|
exports[`Flowcolumns Components should render IconColumn 4`] = `
|
||||||
<td
|
<td
|
||||||
className="col-icon"
|
className="col-icon"
|
||||||
>
|
>
|
||||||
@ -40,7 +40,7 @@ exports[`FlowColumns Components should render IconColumn 4`] = `
|
|||||||
</td>
|
</td>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`FlowColumns Components should render IconColumn 5`] = `
|
exports[`Flowcolumns Components should render IconColumn 5`] = `
|
||||||
<td
|
<td
|
||||||
className="col-icon"
|
className="col-icon"
|
||||||
>
|
>
|
||||||
@ -50,7 +50,7 @@ exports[`FlowColumns Components should render IconColumn 5`] = `
|
|||||||
</td>
|
</td>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`FlowColumns Components should render IconColumn 6`] = `
|
exports[`Flowcolumns Components should render IconColumn 6`] = `
|
||||||
<td
|
<td
|
||||||
className="col-icon"
|
className="col-icon"
|
||||||
>
|
>
|
||||||
@ -60,7 +60,7 @@ exports[`FlowColumns Components should render IconColumn 6`] = `
|
|||||||
</td>
|
</td>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`FlowColumns Components should render IconColumn 7`] = `
|
exports[`Flowcolumns Components should render IconColumn 7`] = `
|
||||||
<td
|
<td
|
||||||
className="col-icon"
|
className="col-icon"
|
||||||
>
|
>
|
||||||
@ -70,7 +70,7 @@ exports[`FlowColumns Components should render IconColumn 7`] = `
|
|||||||
</td>
|
</td>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`FlowColumns Components should render IconColumn 8`] = `
|
exports[`Flowcolumns Components should render IconColumn 8`] = `
|
||||||
<td
|
<td
|
||||||
className="col-icon"
|
className="col-icon"
|
||||||
>
|
>
|
||||||
@ -80,7 +80,7 @@ exports[`FlowColumns Components should render IconColumn 8`] = `
|
|||||||
</td>
|
</td>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`FlowColumns Components should render IconColumn 9`] = `
|
exports[`Flowcolumns Components should render IconColumn 9`] = `
|
||||||
<td
|
<td
|
||||||
className="col-icon"
|
className="col-icon"
|
||||||
>
|
>
|
||||||
@ -90,7 +90,7 @@ exports[`FlowColumns Components should render IconColumn 9`] = `
|
|||||||
</td>
|
</td>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`FlowColumns Components should render MethodColumn 1`] = `
|
exports[`Flowcolumns Components should render MethodColumn 1`] = `
|
||||||
<td
|
<td
|
||||||
className="col-method"
|
className="col-method"
|
||||||
>
|
>
|
||||||
@ -98,7 +98,23 @@ exports[`FlowColumns Components should render MethodColumn 1`] = `
|
|||||||
</td>
|
</td>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`FlowColumns Components should render SizeColumn 1`] = `
|
exports[`Flowcolumns Components should render QuickActionsColumn 1`] = `
|
||||||
|
<td
|
||||||
|
className="col-quickactions"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
className="quickaction"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
className="fa fa-fw fa-ellipsis-h"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`Flowcolumns Components should render SizeColumn 1`] = `
|
||||||
<td
|
<td
|
||||||
className="col-size"
|
className="col-size"
|
||||||
>
|
>
|
||||||
@ -106,7 +122,7 @@ exports[`FlowColumns Components should render SizeColumn 1`] = `
|
|||||||
</td>
|
</td>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`FlowColumns Components should render StatusColumn 1`] = `
|
exports[`Flowcolumns Components should render StatusColumn 1`] = `
|
||||||
<td
|
<td
|
||||||
className="col-status"
|
className="col-status"
|
||||||
style={
|
style={
|
||||||
@ -117,13 +133,13 @@ exports[`FlowColumns Components should render StatusColumn 1`] = `
|
|||||||
/>
|
/>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`FlowColumns Components should render TLSColumn 1`] = `
|
exports[`Flowcolumns Components should render TLSColumn 1`] = `
|
||||||
<td
|
<td
|
||||||
className="col-tls col-tls-http"
|
className="col-tls col-tls-http"
|
||||||
/>
|
/>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`FlowColumns Components should render TimeColumn 1`] = `
|
exports[`Flowcolumns Components should render TimeColumn 1`] = `
|
||||||
<td
|
<td
|
||||||
className="col-time"
|
className="col-time"
|
||||||
>
|
>
|
||||||
@ -131,7 +147,7 @@ exports[`FlowColumns Components should render TimeColumn 1`] = `
|
|||||||
</td>
|
</td>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`FlowColumns Components should render TimeColumn 2`] = `
|
exports[`Flowcolumns Components should render TimeColumn 2`] = `
|
||||||
<td
|
<td
|
||||||
className="col-time"
|
className="col-time"
|
||||||
>
|
>
|
||||||
@ -139,7 +155,7 @@ exports[`FlowColumns Components should render TimeColumn 2`] = `
|
|||||||
</td>
|
</td>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`FlowColumns Components should render TimeStampColumn 1`] = `
|
exports[`Flowcolumns Components should render TimeStampColumn 1`] = `
|
||||||
<td
|
<td
|
||||||
className="col-start"
|
className="col-start"
|
||||||
>
|
>
|
||||||
@ -147,7 +163,7 @@ exports[`FlowColumns Components should render TimeStampColumn 1`] = `
|
|||||||
</td>
|
</td>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`FlowColumns Components should render pathColumn 1`] = `
|
exports[`Flowcolumns Components should render pathColumn 1`] = `
|
||||||
<td
|
<td
|
||||||
className="col-path"
|
className="col-path"
|
||||||
>
|
>
|
||||||
@ -158,7 +174,7 @@ exports[`FlowColumns Components should render pathColumn 1`] = `
|
|||||||
</td>
|
</td>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`FlowColumns Components should render pathColumn 2`] = `
|
exports[`Flowcolumns Components should render pathColumn 2`] = `
|
||||||
<td
|
<td
|
||||||
className="col-path"
|
className="col-path"
|
||||||
>
|
>
|
||||||
|
@ -48,6 +48,19 @@ exports[`FlowRow Component should render correctly 1`] = `
|
|||||||
>
|
>
|
||||||
3s
|
3s
|
||||||
</td>
|
</td>
|
||||||
|
<td
|
||||||
|
className="col-quickactions"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
className="quickaction"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
className="fa fa-fw fa-ellipsis-h"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
<div
|
<div
|
||||||
className="dropdown pull-left btn btn-default"
|
className="dropdown pull-left btn btn-default"
|
||||||
>
|
>
|
||||||
@ -103,20 +116,6 @@ exports[`FlowRow Component should render correctly 1`] = `
|
|||||||
</a>
|
</a>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
|
||||||
|
|
||||||
<a
|
|
||||||
href="#"
|
|
||||||
onClick={[Function]}
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-fw fa-plus"
|
|
||||||
/>
|
|
||||||
Intercept all requests from
|
|
||||||
192.168.0.1
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -44,6 +44,12 @@ exports[`FlowTableHead Component should connect to state 1`] = `
|
|||||||
>
|
>
|
||||||
Time
|
Time
|
||||||
</th>
|
</th>
|
||||||
|
<th
|
||||||
|
className="col-quickactions"
|
||||||
|
onClick={[Function]}
|
||||||
|
>
|
||||||
|
|
||||||
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@ -97,5 +103,11 @@ exports[`FlowTableHead Component should render correctly 1`] = `
|
|||||||
>
|
>
|
||||||
Time
|
Time
|
||||||
</th>
|
</th>
|
||||||
|
<th
|
||||||
|
className="col-quickactions"
|
||||||
|
onClick={[Function]}
|
||||||
|
>
|
||||||
|
|
||||||
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
`;
|
`;
|
||||||
|
@ -16,7 +16,7 @@ describe('FilterInput Component', () => {
|
|||||||
let filterInput = TestUtil.renderIntoDocument(
|
let filterInput = TestUtil.renderIntoDocument(
|
||||||
<FilterInput type='foo' color='red' placeholder='bar' value='' onChange={jest.fn()}/>)
|
<FilterInput type='foo' color='red' placeholder='bar' value='' onChange={jest.fn()}/>)
|
||||||
it('should handle componentWillReceiveProps', () => {
|
it('should handle componentWillReceiveProps', () => {
|
||||||
filterInput.componentWillReceiveProps({value: 'foo'})
|
filterInput.UNSAFE_componentWillReceiveProps({value: 'foo'})
|
||||||
expect(filterInput.state.value).toEqual('foo')
|
expect(filterInput.state.value).toEqual('foo')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`FlowMenu Component should connect to state 1`] = `
|
exports[`FlowMenu Component should connect to state 1`] = `
|
||||||
<div>
|
<div
|
||||||
|
className="flow-menu"
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
className="menu-group"
|
className="menu-group"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="menu-content"
|
className="menu-content"
|
||||||
>
|
>
|
||||||
<div
|
<button
|
||||||
className="btn btn-default"
|
className="btn btn-default"
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
title="[r]eplay flow"
|
title="[r]eplay flow"
|
||||||
@ -17,8 +19,8 @@ exports[`FlowMenu Component should connect to state 1`] = `
|
|||||||
className="fa fa-fw fa-repeat text-primary"
|
className="fa fa-fw fa-repeat text-primary"
|
||||||
/>
|
/>
|
||||||
Replay
|
Replay
|
||||||
</div>
|
</button>
|
||||||
<div
|
<button
|
||||||
className="btn btn-default"
|
className="btn btn-default"
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
title="[D]uplicate flow"
|
title="[D]uplicate flow"
|
||||||
@ -27,8 +29,8 @@ exports[`FlowMenu Component should connect to state 1`] = `
|
|||||||
className="fa fa-fw fa-copy text-info"
|
className="fa fa-fw fa-copy text-info"
|
||||||
/>
|
/>
|
||||||
Duplicate
|
Duplicate
|
||||||
</div>
|
</button>
|
||||||
<div
|
<button
|
||||||
className="btn btn-default"
|
className="btn btn-default"
|
||||||
disabled={true}
|
disabled={true}
|
||||||
title="revert changes to flow [V]"
|
title="revert changes to flow [V]"
|
||||||
@ -37,8 +39,8 @@ exports[`FlowMenu Component should connect to state 1`] = `
|
|||||||
className="fa fa-fw fa-history text-warning"
|
className="fa fa-fw fa-history text-warning"
|
||||||
/>
|
/>
|
||||||
Revert
|
Revert
|
||||||
</div>
|
</button>
|
||||||
<div
|
<button
|
||||||
className="btn btn-default"
|
className="btn btn-default"
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
title="[d]elete flow"
|
title="[d]elete flow"
|
||||||
@ -47,7 +49,7 @@ exports[`FlowMenu Component should connect to state 1`] = `
|
|||||||
className="fa fa-fw fa-trash text-danger"
|
className="fa fa-fw fa-trash text-danger"
|
||||||
/>
|
/>
|
||||||
Delete
|
Delete
|
||||||
</div>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="menu-legend"
|
className="menu-legend"
|
||||||
@ -61,7 +63,7 @@ exports[`FlowMenu Component should connect to state 1`] = `
|
|||||||
<div
|
<div
|
||||||
className="menu-content"
|
className="menu-content"
|
||||||
>
|
>
|
||||||
<div
|
<button
|
||||||
className="btn btn-default"
|
className="btn btn-default"
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
title="download"
|
title="download"
|
||||||
@ -70,7 +72,7 @@ exports[`FlowMenu Component should connect to state 1`] = `
|
|||||||
className="fa fa-fw fa-download"
|
className="fa fa-fw fa-download"
|
||||||
/>
|
/>
|
||||||
Download
|
Download
|
||||||
</div>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="menu-legend"
|
className="menu-legend"
|
||||||
@ -84,7 +86,7 @@ exports[`FlowMenu Component should connect to state 1`] = `
|
|||||||
<div
|
<div
|
||||||
className="menu-content"
|
className="menu-content"
|
||||||
>
|
>
|
||||||
<div
|
<button
|
||||||
className="btn btn-default"
|
className="btn btn-default"
|
||||||
disabled={true}
|
disabled={true}
|
||||||
title="[a]ccept intercepted flow"
|
title="[a]ccept intercepted flow"
|
||||||
@ -93,8 +95,8 @@ exports[`FlowMenu Component should connect to state 1`] = `
|
|||||||
className="fa fa-fw fa-play text-success"
|
className="fa fa-fw fa-play text-success"
|
||||||
/>
|
/>
|
||||||
Resume
|
Resume
|
||||||
</div>
|
</button>
|
||||||
<div
|
<button
|
||||||
className="btn btn-default"
|
className="btn btn-default"
|
||||||
disabled={true}
|
disabled={true}
|
||||||
title="kill intercepted flow [x]"
|
title="kill intercepted flow [x]"
|
||||||
@ -103,7 +105,7 @@ exports[`FlowMenu Component should connect to state 1`] = `
|
|||||||
className="fa fa-fw fa-times text-danger"
|
className="fa fa-fw fa-times text-danger"
|
||||||
/>
|
/>
|
||||||
Abort
|
Abort
|
||||||
</div>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="menu-legend"
|
className="menu-legend"
|
||||||
@ -115,14 +117,16 @@ exports[`FlowMenu Component should connect to state 1`] = `
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`FlowMenu Component should render correctly with flow 1`] = `
|
exports[`FlowMenu Component should render correctly with flow 1`] = `
|
||||||
<div>
|
<div
|
||||||
|
className="flow-menu"
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
className="menu-group"
|
className="menu-group"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="menu-content"
|
className="menu-content"
|
||||||
>
|
>
|
||||||
<div
|
<button
|
||||||
className="btn btn-default"
|
className="btn btn-default"
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
title="[r]eplay flow"
|
title="[r]eplay flow"
|
||||||
@ -131,8 +135,8 @@ exports[`FlowMenu Component should render correctly with flow 1`] = `
|
|||||||
className="fa fa-fw fa-repeat text-primary"
|
className="fa fa-fw fa-repeat text-primary"
|
||||||
/>
|
/>
|
||||||
Replay
|
Replay
|
||||||
</div>
|
</button>
|
||||||
<div
|
<button
|
||||||
className="btn btn-default"
|
className="btn btn-default"
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
title="[D]uplicate flow"
|
title="[D]uplicate flow"
|
||||||
@ -141,8 +145,8 @@ exports[`FlowMenu Component should render correctly with flow 1`] = `
|
|||||||
className="fa fa-fw fa-copy text-info"
|
className="fa fa-fw fa-copy text-info"
|
||||||
/>
|
/>
|
||||||
Duplicate
|
Duplicate
|
||||||
</div>
|
</button>
|
||||||
<div
|
<button
|
||||||
className="btn btn-default"
|
className="btn btn-default"
|
||||||
disabled={false}
|
disabled={false}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
@ -152,8 +156,8 @@ exports[`FlowMenu Component should render correctly with flow 1`] = `
|
|||||||
className="fa fa-fw fa-history text-warning"
|
className="fa fa-fw fa-history text-warning"
|
||||||
/>
|
/>
|
||||||
Revert
|
Revert
|
||||||
</div>
|
</button>
|
||||||
<div
|
<button
|
||||||
className="btn btn-default"
|
className="btn btn-default"
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
title="[d]elete flow"
|
title="[d]elete flow"
|
||||||
@ -162,7 +166,7 @@ exports[`FlowMenu Component should render correctly with flow 1`] = `
|
|||||||
className="fa fa-fw fa-trash text-danger"
|
className="fa fa-fw fa-trash text-danger"
|
||||||
/>
|
/>
|
||||||
Delete
|
Delete
|
||||||
</div>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="menu-legend"
|
className="menu-legend"
|
||||||
@ -176,7 +180,7 @@ exports[`FlowMenu Component should render correctly with flow 1`] = `
|
|||||||
<div
|
<div
|
||||||
className="menu-content"
|
className="menu-content"
|
||||||
>
|
>
|
||||||
<div
|
<button
|
||||||
className="btn btn-default"
|
className="btn btn-default"
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
title="download"
|
title="download"
|
||||||
@ -185,7 +189,7 @@ exports[`FlowMenu Component should render correctly with flow 1`] = `
|
|||||||
className="fa fa-fw fa-download"
|
className="fa fa-fw fa-download"
|
||||||
/>
|
/>
|
||||||
Download
|
Download
|
||||||
</div>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="menu-legend"
|
className="menu-legend"
|
||||||
@ -199,7 +203,7 @@ exports[`FlowMenu Component should render correctly with flow 1`] = `
|
|||||||
<div
|
<div
|
||||||
className="menu-content"
|
className="menu-content"
|
||||||
>
|
>
|
||||||
<div
|
<button
|
||||||
className="btn btn-default"
|
className="btn btn-default"
|
||||||
disabled={false}
|
disabled={false}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
@ -209,8 +213,8 @@ exports[`FlowMenu Component should render correctly with flow 1`] = `
|
|||||||
className="fa fa-fw fa-play text-success"
|
className="fa fa-fw fa-play text-success"
|
||||||
/>
|
/>
|
||||||
Resume
|
Resume
|
||||||
</div>
|
</button>
|
||||||
<div
|
<button
|
||||||
className="btn btn-default"
|
className="btn btn-default"
|
||||||
disabled={false}
|
disabled={false}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
@ -220,7 +224,7 @@ exports[`FlowMenu Component should render correctly with flow 1`] = `
|
|||||||
className="fa fa-fw fa-times text-danger"
|
className="fa fa-fw fa-times text-danger"
|
||||||
/>
|
/>
|
||||||
Abort
|
Abort
|
||||||
</div>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="menu-legend"
|
className="menu-legend"
|
||||||
|
@ -2,7 +2,13 @@
|
|||||||
|
|
||||||
exports[`MainMenu Component should render and connect to state 1`] = `
|
exports[`MainMenu Component should render and connect to state 1`] = `
|
||||||
<div
|
<div
|
||||||
className="menu-main"
|
className="main-menu"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="menu-group"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="menu-content"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="filter-input input-group"
|
className="filter-input input-group"
|
||||||
@ -56,6 +62,19 @@ exports[`MainMenu Component should render and connect to state 1`] = `
|
|||||||
value="~a bar"
|
value="~a bar"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="menu-legend"
|
||||||
|
>
|
||||||
|
Find
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="menu-group"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="menu-content"
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
className="filter-input input-group"
|
className="filter-input input-group"
|
||||||
>
|
>
|
||||||
@ -82,5 +101,22 @@ exports[`MainMenu Component should render and connect to state 1`] = `
|
|||||||
value=""
|
value=""
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<button
|
||||||
|
className="btn-sm btn btn-default"
|
||||||
|
onClick={[Function]}
|
||||||
|
title="[a]ccept all"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
className="fa fa-fw fa-forward text-success"
|
||||||
|
/>
|
||||||
|
Resume All
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="menu-legend"
|
||||||
|
>
|
||||||
|
Intercept
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
@ -8,7 +8,7 @@ exports[`OptionMenu Component should render correctly 1`] = `
|
|||||||
<div
|
<div
|
||||||
className="menu-content"
|
className="menu-content"
|
||||||
>
|
>
|
||||||
<div
|
<button
|
||||||
className="btn btn-default"
|
className="btn btn-default"
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
title="Open Options"
|
title="Open Options"
|
||||||
@ -20,7 +20,7 @@ exports[`OptionMenu Component should render correctly 1`] = `
|
|||||||
<sup>
|
<sup>
|
||||||
alpha
|
alpha
|
||||||
</sup>
|
</sup>
|
||||||
</div>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="menu-legend"
|
className="menu-legend"
|
||||||
|
@ -56,6 +56,12 @@ exports[`FlowTable Component should render correctly 1`] = `
|
|||||||
>
|
>
|
||||||
Time
|
Time
|
||||||
</th>
|
</th>
|
||||||
|
<th
|
||||||
|
className="col-quickactions"
|
||||||
|
onClick={[Function]}
|
||||||
|
>
|
||||||
|
|
||||||
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -24,7 +24,7 @@ describe('Dropdown Component', () => {
|
|||||||
it('should handle open/close action', () => {
|
it('should handle open/close action', () => {
|
||||||
document.body.addEventListener('click', ()=>{})
|
document.body.addEventListener('click', ()=>{})
|
||||||
let tree = dropup.toJSON(),
|
let tree = dropup.toJSON(),
|
||||||
e = { preventDefault: jest.fn() }
|
e = { preventDefault: jest.fn(), stopPropagation: jest.fn() }
|
||||||
tree.children[0].props.onClick(e)
|
tree.children[0].props.onClick(e)
|
||||||
expect(tree).toMatchSnapshot()
|
expect(tree).toMatchSnapshot()
|
||||||
|
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`Button Component should be able to be disabled 1`] = `
|
exports[`Button Component should be able to be disabled 1`] = `
|
||||||
<div
|
<button
|
||||||
className="classname btn btn-default"
|
className="classname btn btn-default"
|
||||||
disabled="true"
|
disabled="true"
|
||||||
>
|
>
|
||||||
<a>
|
<a>
|
||||||
foo
|
foo
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</button>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`Button Component should render correctly 1`] = `
|
exports[`Button Component should render correctly 1`] = `
|
||||||
<div
|
<button
|
||||||
className="classname btn btn-default"
|
className="classname btn btn-default"
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
title="title"
|
title="title"
|
||||||
@ -23,5 +23,5 @@ exports[`Button Component should render correctly 1`] = `
|
|||||||
<a>
|
<a>
|
||||||
foo
|
foo
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</button>
|
||||||
`;
|
`;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {render} from 'react-dom'
|
import {render} from 'react-dom'
|
||||||
import { applyMiddleware, createStore } from 'redux'
|
import {applyMiddleware, compose, createStore} from 'redux'
|
||||||
import {Provider} from 'react-redux'
|
import {Provider} from 'react-redux'
|
||||||
import thunk from 'redux-thunk'
|
import thunk from 'redux-thunk'
|
||||||
|
|
||||||
@ -15,14 +15,16 @@ import { logger } from 'redux-logger'
|
|||||||
|
|
||||||
const middlewares = [thunk];
|
const middlewares = [thunk];
|
||||||
|
|
||||||
|
// logger must be last
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
middlewares.push(logger);
|
middlewares.push(logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
// logger must be last
|
|
||||||
|
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
|
||||||
const store = createStore(
|
const store = createStore(
|
||||||
rootReducer,
|
rootReducer,
|
||||||
applyMiddleware(...middlewares)
|
composeEnhancers(applyMiddleware(...middlewares))
|
||||||
)
|
)
|
||||||
|
|
||||||
useUrlState(store)
|
useUrlState(store)
|
||||||
|
@ -12,7 +12,7 @@ ViewSelector.propTypes = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function ViewSelector ({contentViews, activeView, setContentView}){
|
export function ViewSelector ({contentViews, activeView, setContentView}){
|
||||||
let inner = <span> <b>View:</b> {activeView.toLowerCase()} <span className="caret"></span> </span>
|
let inner = <span> <b>View:</b> {activeView.toLowerCase()} <span className="caret"/> </span>
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dropdown dropup className="pull-left" btnClass="btn btn-default btn-xs" text={inner}>
|
<Dropdown dropup className="pull-left" btnClass="btn btn-default btn-xs" text={inner}>
|
||||||
@ -28,7 +28,7 @@ export function ViewSelector ({contentViews, activeView, setContentView}){
|
|||||||
|
|
||||||
export default connect (
|
export default connect (
|
||||||
state => ({
|
state => ({
|
||||||
contentViews: state.settings.contentViews,
|
contentViews: state.settings.contentViews || [],
|
||||||
activeView: state.ui.flow.contentView,
|
activeView: state.ui.flow.contentView,
|
||||||
}), {
|
}), {
|
||||||
setContentView,
|
setContentView,
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
import React, { Component } from 'react'
|
import React from 'react'
|
||||||
|
import {useDispatch} from 'react-redux'
|
||||||
import classnames from 'classnames'
|
import classnames from 'classnames'
|
||||||
import {RequestUtils, ResponseUtils} from '../../flow/utils.js'
|
import {RequestUtils, ResponseUtils} from '../../flow/utils.js'
|
||||||
import {formatSize, formatTimeDelta, formatTimeStamp} from '../../utils.js'
|
import {formatSize, formatTimeDelta, formatTimeStamp} from '../../utils.js'
|
||||||
|
import * as flowActions from "../../ducks/flows";
|
||||||
|
|
||||||
export const defaultColumnNames = ["tls", "icon", "path", "method", "status", "size", "time"]
|
export const defaultColumnNames = ["tls", "icon", "path", "method", "status", "size", "time"]
|
||||||
|
|
||||||
export function TLSColumn({flow}) {
|
export function TLSColumn({flow}) {
|
||||||
return (
|
return (
|
||||||
<td className={classnames('col-tls', flow.request.scheme === 'https' ? 'col-tls-https' : 'col-tls-http')}></td>
|
<td className={classnames('col-tls', flow.request.scheme === 'https' ? 'col-tls-https' : 'col-tls-http')}/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -17,7 +19,7 @@ TLSColumn.headerName = ''
|
|||||||
export function IconColumn({flow}) {
|
export function IconColumn({flow}) {
|
||||||
return (
|
return (
|
||||||
<td className="col-icon">
|
<td className="col-icon">
|
||||||
<div className={classnames('resource-icon', IconColumn.getIcon(flow))}></div>
|
<div className={classnames('resource-icon', IconColumn.getIcon(flow))}/>
|
||||||
</td>
|
</td>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -60,18 +62,18 @@ export function PathColumn({ flow }) {
|
|||||||
let err;
|
let err;
|
||||||
if (flow.error) {
|
if (flow.error) {
|
||||||
if (flow.error.msg === "Connection killed.") {
|
if (flow.error.msg === "Connection killed.") {
|
||||||
err = <i className="fa fa-fw fa-times pull-right"></i>
|
err = <i className="fa fa-fw fa-times pull-right"/>
|
||||||
} else {
|
} else {
|
||||||
err = <i className="fa fa-fw fa-exclamation pull-right"></i>
|
err = <i className="fa fa-fw fa-exclamation pull-right"/>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<td className="col-path">
|
<td className="col-path">
|
||||||
{flow.request.is_replay && (
|
{flow.request.is_replay && (
|
||||||
<i className="fa fa-fw fa-repeat pull-right"></i>
|
<i className="fa fa-fw fa-repeat pull-right"/>
|
||||||
)}
|
)}
|
||||||
{flow.intercepted && (
|
{flow.intercepted && (
|
||||||
<i className="fa fa-fw fa-pause pull-right"></i>
|
<i className="fa fa-fw fa-pause pull-right"/>
|
||||||
)}
|
)}
|
||||||
{err}
|
{err}
|
||||||
{RequestUtils.pretty_url(flow.request)}
|
{RequestUtils.pretty_url(flow.request)}
|
||||||
@ -96,17 +98,13 @@ export function StatusColumn({ flow }) {
|
|||||||
|
|
||||||
if (flow.response && 100 <= flow.response.status_code && flow.response.status_code < 200) {
|
if (flow.response && 100 <= flow.response.status_code && flow.response.status_code < 200) {
|
||||||
color = 'green'
|
color = 'green'
|
||||||
}
|
} else if (flow.response && 200 <= flow.response.status_code && flow.response.status_code < 300) {
|
||||||
else if (flow.response && 200 <= flow.response.status_code && flow.response.status_code < 300) {
|
|
||||||
color = 'darkgreen'
|
color = 'darkgreen'
|
||||||
}
|
} else if (flow.response && 300 <= flow.response.status_code && flow.response.status_code < 400) {
|
||||||
else if (flow.response && 300 <= flow.response.status_code && flow.response.status_code < 400) {
|
|
||||||
color = 'lightblue'
|
color = 'lightblue'
|
||||||
}
|
} else if (flow.response && 400 <= flow.response.status_code && flow.response.status_code < 500) {
|
||||||
else if (flow.response && 400 <= flow.response.status_code && flow.response.status_code < 500) {
|
|
||||||
color = 'lightred'
|
color = 'lightred'
|
||||||
}
|
} else if (flow.response && 500 <= flow.response.status_code && flow.response.status_code < 600) {
|
||||||
else if (flow.response && 500 <= flow.response.status_code && flow.response.status_code < 600) {
|
|
||||||
color = 'lightred'
|
color = 'lightred'
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,7 +163,33 @@ export function TimeStampColumn({ flow }) {
|
|||||||
TimeStampColumn.headerClass = 'col-timestamp'
|
TimeStampColumn.headerClass = 'col-timestamp'
|
||||||
TimeStampColumn.headerName = 'TimeStamp'
|
TimeStampColumn.headerName = 'TimeStamp'
|
||||||
|
|
||||||
export default [
|
export function QuickActionsColumn({flow}) {
|
||||||
|
const dispatch = useDispatch()
|
||||||
|
|
||||||
|
function resume(e) {
|
||||||
|
dispatch(flowActions.resume(flow))
|
||||||
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<td className="col-quickactions">
|
||||||
|
<div>
|
||||||
|
<div className="quickaction"><i className="fa fa-fw fa-ellipsis-h"/></div>
|
||||||
|
{flow.intercepted
|
||||||
|
? <div className="quickaction" onClick={resume}><i className="fa fa-fw fa-play text-success"/></div>
|
||||||
|
: null}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
QuickActionsColumn.headerClass = 'col-quickactions'
|
||||||
|
QuickActionsColumn.headerName = ''
|
||||||
|
|
||||||
|
|
||||||
|
export const columns = {};
|
||||||
|
for (let col of [
|
||||||
TLSColumn,
|
TLSColumn,
|
||||||
IconColumn,
|
IconColumn,
|
||||||
PathColumn,
|
PathColumn,
|
||||||
@ -174,4 +198,7 @@ export default [
|
|||||||
TimeStampColumn,
|
TimeStampColumn,
|
||||||
SizeColumn,
|
SizeColumn,
|
||||||
TimeColumn,
|
TimeColumn,
|
||||||
]
|
QuickActionsColumn,
|
||||||
|
]) {
|
||||||
|
columns[col.name.replace(/Column$/, "").toLowerCase()] = col;
|
||||||
|
}
|
||||||
|
@ -2,7 +2,7 @@ import React from 'react'
|
|||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import {connect} from 'react-redux'
|
import {connect} from 'react-redux'
|
||||||
import classnames from 'classnames'
|
import classnames from 'classnames'
|
||||||
import columns, {defaultColumnNames} from './FlowColumns'
|
import {columns, defaultColumnNames} from './FlowColumns'
|
||||||
|
|
||||||
import {setSort} from '../../ducks/flows'
|
import {setSort} from '../../ducks/flows'
|
||||||
|
|
||||||
@ -14,16 +14,10 @@ FlowTableHead.propTypes = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getDisplayColumns(displayColumnNames) {
|
export function getDisplayColumns(displayColumnNames) {
|
||||||
let displayColumns = []
|
|
||||||
if (typeof displayColumnNames == "undefined") {
|
if (typeof displayColumnNames == "undefined") {
|
||||||
return columns
|
return Object.values(columns)
|
||||||
}
|
}
|
||||||
for (const column of columns) {
|
return displayColumnNames.map(x => columns[x]).concat([columns.quickactions]);
|
||||||
if (displayColumnNames.includes(column.name.slice(0,-6).toLowerCase())) {
|
|
||||||
displayColumns.push(column)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return displayColumns
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function FlowTableHead({sortColumn, sortDesc, setSort, displayColumnNames}) {
|
export function FlowTableHead({sortColumn, sortDesc, setSort, displayColumnNames}) {
|
||||||
|
@ -13,7 +13,7 @@ function Footer({ settings }) {
|
|||||||
stickyauth, stickycookie, stream_large_bodies, listen_host, listen_port, version, server} = settings;
|
stickyauth, stickycookie, stream_large_bodies, listen_host, listen_port, version, server} = settings;
|
||||||
return (
|
return (
|
||||||
<footer>
|
<footer>
|
||||||
{mode && mode != "regular" && (
|
{mode && mode !== "regular" && (
|
||||||
<span className="label label-success">{mode} mode</span>
|
<span className="label label-success">{mode} mode</span>
|
||||||
)}
|
)}
|
||||||
{intercept && (
|
{intercept && (
|
||||||
@ -25,8 +25,8 @@ function Footer({ settings }) {
|
|||||||
{no_upstream_cert && (
|
{no_upstream_cert && (
|
||||||
<span className="label label-success">no-upstream-cert</span>
|
<span className="label label-success">no-upstream-cert</span>
|
||||||
)}
|
)}
|
||||||
{rawtcp && (
|
{!rawtcp && (
|
||||||
<span className="label label-success">raw-tcp</span>
|
<span className="label label-success">no-raw-tcp</span>
|
||||||
)}
|
)}
|
||||||
{!http2 && (
|
{!http2 && (
|
||||||
<span className="label label-success">no-http2</span>
|
<span className="label label-success">no-http2</span>
|
||||||
|
@ -22,7 +22,7 @@ export function FlowMenu({ flow, resumeFlow, killFlow, replayFlow, duplicateFlow
|
|||||||
if (!flow)
|
if (!flow)
|
||||||
return <div/>
|
return <div/>
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className="flow-menu">
|
||||||
<HideInStatic>
|
<HideInStatic>
|
||||||
<div className="menu-group">
|
<div className="menu-group">
|
||||||
<div className="menu-content">
|
<div className="menu-content">
|
||||||
@ -72,8 +72,6 @@ export function FlowMenu({ flow, resumeFlow, killFlow, replayFlow, duplicateFlow
|
|||||||
<div className="menu-legend">Interception</div>
|
<div className="menu-legend">Interception</div>
|
||||||
</div>
|
</div>
|
||||||
</HideInStatic>
|
</HideInStatic>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,37 @@
|
|||||||
import React, { Component } from "react"
|
import React from "react"
|
||||||
import PropTypes from 'prop-types'
|
|
||||||
import {connect} from "react-redux"
|
import {connect} from "react-redux"
|
||||||
import FilterInput from "./FilterInput"
|
import FilterInput from "./FilterInput"
|
||||||
import {update as updateSettings} from "../../ducks/settings"
|
import {update as updateSettings} from "../../ducks/settings"
|
||||||
|
import * as flowsActions from "../../ducks/flows"
|
||||||
import {setFilter, setHighlight} from "../../ducks/flows"
|
import {setFilter, setHighlight} from "../../ducks/flows"
|
||||||
|
import Button from "../common/Button"
|
||||||
|
|
||||||
MainMenu.title = "Start"
|
MainMenu.title = "Start"
|
||||||
|
|
||||||
export default function MainMenu() {
|
export default function MainMenu() {
|
||||||
return (
|
return (
|
||||||
<div className="menu-main">
|
<div className="main-menu">
|
||||||
|
<div className="menu-group">
|
||||||
|
<div className="menu-content">
|
||||||
<FlowFilterInput/>
|
<FlowFilterInput/>
|
||||||
<HighlightInput/>
|
<HighlightInput/>
|
||||||
|
</div>
|
||||||
|
<div className="menu-legend">Find</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="menu-group">
|
||||||
|
<div className="menu-content">
|
||||||
<InterceptInput/>
|
<InterceptInput/>
|
||||||
|
<ResumeAll/>
|
||||||
|
</div>
|
||||||
|
<div className="menu-legend">Intercept</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setIntercept(intercept) {
|
export function setIntercept(intercept) {
|
||||||
updateSettings({ intercept })
|
return updateSettings({intercept})
|
||||||
}
|
}
|
||||||
|
|
||||||
const InterceptInput = connect(
|
const InterceptInput = connect(
|
||||||
@ -50,3 +63,17 @@ const HighlightInput = connect(
|
|||||||
}),
|
}),
|
||||||
{onChange: setHighlight}
|
{onChange: setHighlight}
|
||||||
)(FilterInput);
|
)(FilterInput);
|
||||||
|
|
||||||
|
export function ResumeAll({resumeAll}) {
|
||||||
|
return (
|
||||||
|
<Button className="btn-sm" title="[a]ccept all"
|
||||||
|
icon="fa-forward text-success" onClick={() => resumeAll()}>
|
||||||
|
Resume All
|
||||||
|
</Button>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
ResumeAll = connect(
|
||||||
|
null,
|
||||||
|
{resumeAll: flowsActions.resumeAll}
|
||||||
|
)(ResumeAll)
|
||||||
|
@ -4,19 +4,19 @@ import classnames from "classnames"
|
|||||||
|
|
||||||
Button.propTypes = {
|
Button.propTypes = {
|
||||||
onClick: PropTypes.func.isRequired,
|
onClick: PropTypes.func.isRequired,
|
||||||
children: PropTypes.node.isRequired,
|
children: PropTypes.node,
|
||||||
icon: PropTypes.string,
|
icon: PropTypes.string,
|
||||||
title: PropTypes.string,
|
title: PropTypes.string,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Button({ onClick, children, icon, disabled, className, title }) {
|
export default function Button({ onClick, children, icon, disabled, className, title }) {
|
||||||
return (
|
return (
|
||||||
<div className={classnames(className, 'btn btn-default')}
|
<button className={classnames(className, 'btn btn-default')}
|
||||||
onClick={disabled ? undefined : onClick}
|
onClick={disabled ? undefined : onClick}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
title={title}>
|
title={title}>
|
||||||
{icon && (<i className={"fa fa-fw " + icon}/> )}
|
{icon && (<i className={"fa fa-fw " + icon}/> )}
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</button>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@ export default class Dropdown extends Component {
|
|||||||
if (this.state.open) {
|
if (this.state.open) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
e.stopPropagation();
|
||||||
this.setState({open: !this.state.open})
|
this.setState({open: !this.state.open})
|
||||||
document.addEventListener('click', this.close)
|
document.addEventListener('click', this.close)
|
||||||
}
|
}
|
||||||
|
@ -2544,6 +2544,7 @@ dedent@^0.7.0:
|
|||||||
deep-diff@^0.3.5:
|
deep-diff@^0.3.5:
|
||||||
version "0.3.8"
|
version "0.3.8"
|
||||||
resolved "https://registry.yarnpkg.com/deep-diff/-/deep-diff-0.3.8.tgz#c01de63efb0eec9798801d40c7e0dae25b582c84"
|
resolved "https://registry.yarnpkg.com/deep-diff/-/deep-diff-0.3.8.tgz#c01de63efb0eec9798801d40c7e0dae25b582c84"
|
||||||
|
integrity sha1-wB3mPvsO7JeYgB1Ax+Da4ltYLIQ=
|
||||||
|
|
||||||
deep-extend@^0.6.0:
|
deep-extend@^0.6.0:
|
||||||
version "0.6.0"
|
version "0.6.0"
|
||||||
|
Loading…
Reference in New Issue
Block a user