Fixing acceptance tests (#900)

This commit is contained in:
gadotroee 2022-03-21 14:21:08 +02:00 committed by GitHub
parent 5455220a3a
commit a4d0e250c9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 142 additions and 148 deletions

View File

@ -1,8 +1,7 @@
const columns = {podName : 1, namespace : 2, tapping : 3}; const columns = {podName : 1, namespace : 2, tapping : 3};
const greenStatusImageSrc = '/static/media/success.662997eb.svg';
function getDomPathInStatusBar(line, column) { function getDomPathInStatusBar(line, column) {
return `.expandedStatusBar > :nth-child(2) > > :nth-child(2) > :nth-child(${line}) > :nth-child(${column})`; return `[data-cy="expandedStatusBar"] > :nth-child(2) > > :nth-child(2) > :nth-child(${line}) > :nth-child(${column})`;
} }
export function checkLine(line, expectedValues) { export function checkLine(line, expectedValues) {
@ -12,14 +11,14 @@ export function checkLine(line, expectedValues) {
cy.get(getDomPathInStatusBar(line, columns.namespace)).invoke('text').then(namespaceValue => { cy.get(getDomPathInStatusBar(line, columns.namespace)).invoke('text').then(namespaceValue => {
expect(namespaceValue).to.equal(expectedValues.namespace); expect(namespaceValue).to.equal(expectedValues.namespace);
cy.get(getDomPathInStatusBar(line, columns.tapping)).children().should('have.attr', 'src', greenStatusImageSrc); cy.get(getDomPathInStatusBar(line, columns.tapping)).children().should('have.attr', 'src').and("match", /success.*\.svg/);
}); });
}); });
} }
export function findLineAndCheck(expectedValues) { export function findLineAndCheck(expectedValues) {
cy.get('.expandedStatusBar > :nth-child(2) > > :nth-child(2) > > :nth-child(1)').then(pods => { cy.get('[data-cy="expandedStatusBar"] > :nth-child(2) > > :nth-child(2) > > :nth-child(1)').then(pods => {
cy.get('.expandedStatusBar > :nth-child(2) > > :nth-child(2) > > :nth-child(2)').then(namespaces => { cy.get('[data-cy="expandedStatusBar"] > :nth-child(2) > > :nth-child(2) > > :nth-child(2)').then(namespaces => {
// organizing namespaces array // organizing namespaces array
const podObjectsArray = Object.values(pods ?? {}); const podObjectsArray = Object.values(pods ?? {});
const namespacesObjectsArray = Object.values(namespaces ?? {}); const namespacesObjectsArray = Object.values(namespaces ?? {});

View File

@ -45,7 +45,7 @@ export function leftTextCheck(entryNum, path, expectedText) {
export function leftOnHoverCheck(entryNum, path, filterName) { export function leftOnHoverCheck(entryNum, path, filterName) {
cy.get(`#list #entry-${entryNum} ${path}`).trigger('mouseover'); cy.get(`#list #entry-${entryNum} ${path}`).trigger('mouseover');
cy.get(`#list #entry-${entryNum} .Queryable-Tooltip`).invoke('text').should('match', new RegExp(filterName)); cy.get(`#list #entry-${entryNum} [data-cy='QueryableTooltip']`).invoke('text').should('match', new RegExp(filterName));
} }
export function rightTextCheck(path, expectedText) { export function rightTextCheck(path, expectedText) {
@ -54,7 +54,7 @@ export function rightTextCheck(path, expectedText) {
export function rightOnHoverCheck(path, expectedText) { export function rightOnHoverCheck(path, expectedText) {
cy.get(`#rightSideContainer ${path}`).trigger('mouseover'); cy.get(`#rightSideContainer ${path}`).trigger('mouseover');
cy.get(`#rightSideContainer .Queryable-Tooltip`).invoke('text').should('match', new RegExp(expectedText)); cy.get(`#rightSideContainer [data-cy='QueryableTooltip']`).invoke('text').should('match', new RegExp(expectedText));
} }
export function checkThatAllEntriesShown() { export function checkThatAllEntriesShown() {

View File

@ -8,6 +8,6 @@ it('check', function () {
cy.visit(`http://localhost:${port}`); cy.visit(`http://localhost:${port}`);
cy.wait('@statusTap').its('response.statusCode').should('match', /^2\d{2}/); cy.wait('@statusTap').its('response.statusCode').should('match', /^2\d{2}/);
cy.get('.podsCount').trigger('mouseover'); cy.get(`[data-cy="expandedStatusBar"]`).trigger('mouseover',{force: true});
findLineAndCheck(getExpectedDetailsDict(podName, namespace)); findLineAndCheck(getExpectedDetailsDict(podName, namespace));
}); });

View File

@ -2,7 +2,7 @@ import {findLineAndCheck, getExpectedDetailsDict} from '../testHelpers/StatusBar
it('opening', function () { it('opening', function () {
cy.visit(Cypress.env('testUrl')); cy.visit(Cypress.env('testUrl'));
cy.get('.podsCount').trigger('mouseover'); cy.get(`[data-cy="podsCountText"]`).trigger('mouseover');
}); });
[1, 2, 3].map(doItFunc); [1, 2, 3].map(doItFunc);

View File

@ -3,9 +3,9 @@ import {getExpectedDetailsDict, checkLine} from '../testHelpers/StatusBarHelper'
it('opening', function () { it('opening', function () {
cy.visit(Cypress.env('testUrl')); cy.visit(Cypress.env('testUrl'));
cy.get('.podsCount').trigger('mouseover'); cy.get(`[data-cy="podsCountText"]`).trigger('mouseover');
cy.get('.expandedStatusBar > :nth-child(2) > > :nth-child(2) >').should('have.length', 1); // one line cy.get('[data-cy="expandedStatusBar"] > :nth-child(2) > > :nth-child(2) >').should('have.length', 1); // one line
checkLine(1, getExpectedDetailsDict(Cypress.env('name'), Cypress.env('namespace'))); checkLine(1, getExpectedDetailsDict(Cypress.env('name'), Cypress.env('namespace')));
}); });

View File

@ -26,7 +26,7 @@ it('opening mizu', function () {
verifyMinimumEntries(); verifyMinimumEntries();
it('top bar check', function () { it('top bar check', function () {
cy.get('.podsCount').trigger('mouseover'); cy.get(`[data-cy="podsCountText"]`).trigger('mouseover');
podsArray.map(findLineAndCheck); podsArray.map(findLineAndCheck);
cy.reload(); cy.reload();
}); });
@ -205,6 +205,7 @@ function checkFilter(filterDetails){
// checks the hover on the last entry (the only one in DOM at the beginning) // checks the hover on the last entry (the only one in DOM at the beginning)
leftOnHoverCheck(totalEntries - 1, leftSidePath, name); leftOnHoverCheck(totalEntries - 1, leftSidePath, name);
cy.get('.w-tc-editor-text').clear();
// applying the filter with alt+enter or with the button // applying the filter with alt+enter or with the button
cy.get('.w-tc-editor-text').type(`${name}${applyByEnter ? '{alt+enter}' : ''}`); cy.get('.w-tc-editor-text').type(`${name}${applyByEnter ? '{alt+enter}' : ''}`);
cy.get('.w-tc-editor').should('have.attr', 'style').and('include', Cypress.env('greenFilterColor')); cy.get('.w-tc-editor').should('have.attr', 'style').and('include', Cypress.env('greenFilterColor'));

View File

@ -5,10 +5,10 @@ import Api, {getWebsocketUrl} from "./api";
const api = Api.getInstance() const api = Api.getInstance()
const App = () => { const App = () => {
const {message,error,isOpen, openSocket, closeSocket, sendQuery} = useWS(getWebsocketUrl()) const {message,error,isOpen, openSocket, closeSocket, sendQueryWhenWsOpen} = useWS(getWebsocketUrl())
const trafficViewerApi = {...api, webSocket:{open : openSocket, close: closeSocket, sendQuery: sendQuery}} const trafficViewerApi = {...api, webSocket:{open : openSocket, close: closeSocket, sendQueryWhenWsOpen: sendQueryWhenWsOpen}}
sendQuery(DEFAULT_QUERY); sendQueryWhenWsOpen(DEFAULT_QUERY);
useEffect(() => { useEffect(() => {
return () =>{ return () =>{

View File

@ -1,6 +1,6 @@
{ {
"name": "@up9/mizu-common", "name": "@up9/mizu-common",
"version": "1.0.125", "version": "1.0.128",
"description": "Made with create-react-library", "description": "Made with create-react-library",
"author": "", "author": "",
"license": "MIT", "license": "MIT",
@ -30,7 +30,6 @@
"react":"^17.0.2", "react":"^17.0.2",
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
"recoil": "^0.5.2", "recoil": "^0.5.2",
"react-copy-to-clipboard": "^5.0.3", "react-copy-to-clipboard": "^5.0.3",
"@types/jest": "^26.0.22", "@types/jest": "^26.0.22",
"@types/node": "^12.20.10" "@types/node": "^12.20.10"

View File

@ -8,7 +8,8 @@ import { EntryDetailed } from "./EntryDetailed";
import playIcon from 'assets/run.svg'; import playIcon from 'assets/run.svg';
import pauseIcon from 'assets/pause.svg'; import pauseIcon from 'assets/pause.svg';
import variables from '../../variables.module.scss'; import variables from '../../variables.module.scss';
import { toast } from 'react-toastify'; import { toast,ToastContainer } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import debounce from 'lodash/debounce'; import debounce from 'lodash/debounce';
import { RecoilRoot, RecoilState, useRecoilState, useRecoilValue, useSetRecoilState } from "recoil"; import { RecoilRoot, RecoilState, useRecoilState, useRecoilValue, useSetRecoilState } from "recoil";
import entriesAtom from "../../recoil/entries"; import entriesAtom from "../../recoil/entries";
@ -21,7 +22,6 @@ import TrafficViewerApi from "./TrafficViewerApi";
import { StatusBar } from "../UI/StatusBar"; import { StatusBar } from "../UI/StatusBar";
import tappingStatusAtom from "../../recoil/tappingStatus/atom"; import tappingStatusAtom from "../../recoil/tappingStatus/atom";
const useLayoutStyles = makeStyles(() => ({ const useLayoutStyles = makeStyles(() => ({
details: { details: {
flex: "0 0 50%", flex: "0 0 50%",
@ -45,26 +45,22 @@ const useLayoutStyles = makeStyles(() => ({
interface TrafficViewerProps { interface TrafficViewerProps {
setAnalyzeStatus?: (status: any) => void; setAnalyzeStatus?: (status: any) => void;
api?: any api?: any
message?: {}
error?: {}
isWebSocketOpen: boolean
trafficViewerApiProp: TrafficViewerApi, trafficViewerApiProp: TrafficViewerApi,
actionButtons?: JSX.Element, actionButtons?: JSX.Element,
isShowStatusBar?: boolean isShowStatusBar?: boolean,
webSocketUrl : string
} }
const TrafficViewer: React.FC<TrafficViewerProps> = ({ setAnalyzeStatus, message, error, isWebSocketOpen, trafficViewerApiProp, actionButtons, isShowStatusBar }) => { export const TrafficViewer : React.FC<TrafficViewerProps> = ({setAnalyzeStatus, trafficViewerApiProp, actionButtons,isShowStatusBar,webSocketUrl}) => {
const classes = useLayoutStyles(); const classes = useLayoutStyles();
const [entries, setEntries] = useRecoilState(entriesAtom); const [entries, setEntries] = useRecoilState(entriesAtom);
const [focusedEntryId, setFocusedEntryId] = useRecoilState(focusedEntryIdAtom); const [focusedEntryId, setFocusedEntryId] = useRecoilState(focusedEntryIdAtom);
const [wsConnection, setWsConnection] = useRecoilState(websocketConnectionAtom); const [wsConnection, setWsConnection] = useRecoilState(websocketConnectionAtom);
const query = useRecoilValue(queryAtom); const query = useRecoilValue(queryAtom);
const [queryToSend, setQueryToSend] = useState("")
const setTrafficViewerApiState = useSetRecoilState(trafficViewerApiAtom as RecoilState<TrafficViewerApi>) const setTrafficViewerApiState = useSetRecoilState(trafficViewerApiAtom as RecoilState<TrafficViewerApi>)
const [tappingStatus, setTappingStatus] = useRecoilState(tappingStatusAtom); const [tappingStatus, setTappingStatus] = useRecoilState(tappingStatusAtom);
const [noMoreDataTop, setNoMoreDataTop] = useState(false); const [noMoreDataTop, setNoMoreDataTop] = useState(false);
const [isSnappedToBottom, setIsSnappedToBottom] = useState(true); const [isSnappedToBottom, setIsSnappedToBottom] = useState(true);
@ -107,6 +103,7 @@ const TrafficViewer: React.FC<TrafficViewerProps> = ({ setAnalyzeStatus, message
handleQueryChange(query); handleQueryChange(query);
}, [query, handleQueryChange]); }, [query, handleQueryChange]);
const ws = useRef(null);
const listEntry = useRef(null); const listEntry = useRef(null);
const openWebSocket = (query: string, resetEntries: boolean) => { const openWebSocket = (query: string, resetEntries: boolean) => {
@ -117,98 +114,99 @@ const TrafficViewer: React.FC<TrafficViewerProps> = ({ setAnalyzeStatus, message
setLeftOffTop(null); setLeftOffTop(null);
setNoMoreDataTop(false); setNoMoreDataTop(false);
} }
setQueryToSend(query) ws.current = new WebSocket(webSocketUrl);
trafficViewerApiProp.webSocket.open(); ws.current.onopen = () => {
} setWsConnection(WsConnectionStatus.Connected);
sendQueryWhenWsOpen(query);
const onmessage = useCallback((e) => {
if (!e?.data) return;
const message = JSON.parse(e.data);
switch (message.messageType) {
case "entry":
const entry = message.data;
if (!focusedEntryId) setFocusedEntryId(entry.id.toString());
const newEntries = [...entries, entry];
if (newEntries.length === 10001) {
setLeftOffTop(newEntries[0].entry.id);
newEntries.shift();
setNoMoreDataTop(false);
}
setEntries(newEntries);
break;
case "status":
setTappingStatus(message.tappingStatus);
break;
case "analyzeStatus":
setAnalyzeStatus(message.analyzeStatus);
break;
case "outboundLink":
onTLSDetected(message.Data.DstIP);
break;
case "toast":
toast[message.data.type](message.data.text, {
position: "bottom-right",
theme: "colored",
autoClose: message.data.autoClose,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
progress: undefined,
});
break;
case "queryMetadata":
setQueriedCurrent(queriedCurrent + message.data.current);
setQueriedTotal(message.data.total);
setLeftOffBottom(message.data.leftOff);
setTruncatedTimestamp(message.data.truncatedTimestamp);
if (leftOffTop === null) {
setLeftOffTop(message.data.leftOff - 1);
}
break;
case "startTime":
setStartTime(message.data);
break;
default:
console.error(
`unsupported websocket message type, Got: ${message.messageType}`
);
} }
ws.current.onclose = () => {
// eslint-disable-next-line react-hooks/exhaustive-deps setWsConnection(WsConnectionStatus.Closed);
}, [message]); }
ws.current.onerror = (event) => {
useEffect(() => { console.error("WebSocket error:", event);
onmessage(message) if (query) {
}, [message, onmessage]) openWebSocket(`(${query}) and leftOff(${leftOffBottom})`, false);
} else {
useEffect(() => { openWebSocket(`leftOff(${leftOffBottom})`, false);
onerror(error) }
}, [error])
useEffect(() => {
isWebSocketOpen ? setWsConnection(WsConnectionStatus.Connected) : setWsConnection(WsConnectionStatus.Closed)
trafficViewerApiProp.webSocket.sendQuery(queryToSend)
}, [isWebSocketOpen, queryToSend, setWsConnection])
const onerror = (event) => {
console.error("WebSocket error:", event);
if (query) {
openWebSocket(`(${query}) and leftOff(${leftOffBottom})`, false);
} else {
openWebSocket(`leftOff(${leftOffBottom})`, false);
} }
} }
const sendQueryWhenWsOpen = (query) => {
setTimeout(() => {
if (ws?.current?.readyState === WebSocket.OPEN) {
ws.current.send(JSON.stringify({"query": query, "enableFullEntries": false}));
} else {
sendQueryWhenWsOpen(query);
}
}, 500)
}
if (ws.current) {
ws.current.onmessage = (e) => {
if (!e?.data) return;
const message = JSON.parse(e.data);
switch (message.messageType) {
case "entry":
const entry = message.data;
if (!focusedEntryId) setFocusedEntryId(entry.id.toString());
const newEntries = [...entries, entry];
if (newEntries.length === 10001) {
setLeftOffTop(newEntries[0].entry.id);
newEntries.shift();
setNoMoreDataTop(false);
}
setEntries(newEntries);
break;
case "status":
setTappingStatus(message.tappingStatus);
break;
case "analyzeStatus":
setAnalyzeStatus(message.analyzeStatus);
break;
case "outboundLink":
onTLSDetected(message.Data.DstIP);
break;
case "toast":
toast[message.data.type](message.data.text, {
position: "bottom-right",
theme: "colored",
autoClose: message.data.autoClose,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
progress: undefined,
});
break;
case "queryMetadata":
setQueriedCurrent(queriedCurrent + message.data.current);
setQueriedTotal(message.data.total);
setLeftOffBottom(message.data.leftOff);
setTruncatedTimestamp(message.data.truncatedTimestamp);
if (leftOffTop === null) {
setLeftOffTop(message.data.leftOff - 1);
}
break;
case "startTime":
setStartTime(message.data);
break;
default:
console.error(
`unsupported websocket message type, Got: ${message.messageType}`
);
}
};
}
useEffect(() => { useEffect(() => {
setTrafficViewerApiState({...trafficViewerApiProp, webSocket : {close : () => ws.current.close()}});
(async () => { (async () => {
setTrafficViewerApiState(trafficViewerApiProp)
openWebSocket("leftOff(-1)", true); openWebSocket("leftOff(-1)", true);
try { try{
const tapStatusResponse = await trafficViewerApiProp.tapStatus(); const tapStatusResponse = await trafficViewerApiProp.tapStatus();
setTappingStatus(tapStatusResponse); setTappingStatus(tapStatusResponse);
if (setAnalyzeStatus) { if(setAnalyzeStatus) {
const analyzeStatusResponse = await trafficViewerApiProp.analyzeStatus(); const analyzeStatusResponse = await trafficViewerApiProp.analyzeStatus();
setAnalyzeStatus(analyzeStatusResponse); setAnalyzeStatus(analyzeStatusResponse);
} }
@ -220,8 +218,8 @@ const TrafficViewer: React.FC<TrafficViewerProps> = ({ setAnalyzeStatus, message
}, []); }, []);
const toggleConnection = () => { const toggleConnection = () => {
if (wsConnection === WsConnectionStatus.Closed) { ws.current.close();
if (wsConnection !== WsConnectionStatus.Connected) {
if (query) { if (query) {
openWebSocket(`(${query}) and leftOff(-1)`, true); openWebSocket(`(${query}) and leftOff(-1)`, true);
} else { } else {
@ -230,10 +228,6 @@ const TrafficViewer: React.FC<TrafficViewerProps> = ({ setAnalyzeStatus, message
scrollableRef.current.jumpToBottom(); scrollableRef.current.jumpToBottom();
setIsSnappedToBottom(true); setIsSnappedToBottom(true);
} }
else if (wsConnection === WsConnectionStatus.Connected) {
trafficViewerApiProp.webSocket.close()
setWsConnection(WsConnectionStatus.Closed);
}
} }
const onTLSDetected = (destAddress: string) => { const onTLSDetected = (destAddress: string) => {
@ -270,7 +264,7 @@ const TrafficViewer: React.FC<TrafficViewerProps> = ({ setAnalyzeStatus, message
const onSnapBrokenEvent = () => { const onSnapBrokenEvent = () => {
setIsSnappedToBottom(false); setIsSnappedToBottom(false);
if (wsConnection === WsConnectionStatus.Connected) { if (wsConnection === WsConnectionStatus.Connected) {
trafficViewerApiProp.webSocket.close() ws.current.close();
} }
} }
@ -330,16 +324,17 @@ const TrafficViewer: React.FC<TrafficViewerProps> = ({ setAnalyzeStatus, message
setAddressesWithTLS={setAddressesWithTLS} setAddressesWithTLS={setAddressesWithTLS}
userDismissedTLSWarning={userDismissedTLSWarning} userDismissedTLSWarning={userDismissedTLSWarning}
setUserDismissedTLSWarning={setUserDismissedTLSWarning} /> setUserDismissedTLSWarning={setUserDismissedTLSWarning} />
<ToastContainer/>
</div> </div>
); );
}; };
const MemoiedTrafficViewer = React.memo(TrafficViewer) const MemoiedTrafficViewer = React.memo(TrafficViewer)
const TrafficViewerContainer: React.FC<TrafficViewerProps> = ({ setAnalyzeStatus, message, isWebSocketOpen, trafficViewerApiProp, actionButtons, isShowStatusBar = true }) => { const TrafficViewerContainer: React.FC<TrafficViewerProps> = ({ setAnalyzeStatus, trafficViewerApiProp, actionButtons, isShowStatusBar = true ,webSocketUrl}) => {
return <RecoilRoot> return <RecoilRoot>
<MemoiedTrafficViewer message={message} isWebSocketOpen={isWebSocketOpen} actionButtons={actionButtons} isShowStatusBar={isShowStatusBar} <MemoiedTrafficViewer actionButtons={actionButtons} isShowStatusBar={isShowStatusBar} webSocketUrl={webSocketUrl}
trafficViewerApiProp={trafficViewerApiProp} setAnalyzeStatus={setAnalyzeStatus} /> trafficViewerApiProp={trafficViewerApiProp} setAnalyzeStatus={setAnalyzeStatus} />
</RecoilRoot> </RecoilRoot>
} }
export default TrafficViewerContainer export default TrafficViewerContainer

View File

@ -6,10 +6,8 @@ type TrafficViewerApi = {
getEntry : (entryId : any, query:string) => any getEntry : (entryId : any, query:string) => any
getRecentTLSLinks : () => any, getRecentTLSLinks : () => any,
webSocket : { webSocket : {
open : () => {}, close : () => {}
close : () => {},
sendQuery : (query:string) => {}
} }
} }
export default TrafficViewerApi export default TrafficViewerApi

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -54,7 +54,7 @@ const Queryable: React.FC<Props> = ({query, style, iconStyle, className, useTool
{flipped && addButton} {flipped && addButton}
{children} {children}
{!flipped && addButton} {!flipped && addButton}
{useTooltip && showTooltip && <span className={QueryableStyle.QueryableTooltip} style={tooltipStyle}>{query}</span>} {useTooltip && showTooltip && <span data-cy={"QueryableTooltip"} className={QueryableStyle.QueryableTooltip} style={tooltipStyle}>{query}</span>}
</div> </div>
); );
}; };

View File

@ -11,15 +11,14 @@ const pluralize = (noun: string, amount: number) => {
} }
export const StatusBar = () => { export const StatusBar = () => {
const tappingStatus = useRecoilValue(tappingStatusAtom); const tappingStatus = useRecoilValue(tappingStatusAtom);
const [expandedBar, setExpandedBar] = useState(false); const [expandedBar, setExpandedBar] = useState(false);
const {uniqueNamespaces, amountOfPods, amountOfTappedPods, amountOfUntappedPods} = useRecoilValue(tappingStatusDetails); const {uniqueNamespaces, amountOfPods, amountOfTappedPods, amountOfUntappedPods} = useRecoilValue(tappingStatusDetails);
return <div className={`${style.statusBar} ${(expandedBar ? `${style.expandedStatusBar}` : "")}`} onMouseOver={() => setExpandedBar(true)} onMouseLeave={() => setExpandedBar(false)}> return <div className={`${style.statusBar} ${(expandedBar ? `${style.expandedStatusBar}` : "")}`} onMouseOver={() => setExpandedBar(true)} onMouseLeave={() => setExpandedBar(false)} data-cy="expandedStatusBar">
<div className={style.podsCount}> <div className={style.podsCount}>
{tappingStatus.some(pod => !pod.isTapped) && <img src={warningIcon} alt="warning"/>} {tappingStatus.some(pod => !pod.isTapped) && <img src={warningIcon} alt="warning"/>}
<span className={style.podsCountText}> <span className={style.podsCountText} data-cy="podsCountText">
{`Tapping ${amountOfUntappedPods > 0 ? amountOfTappedPods + " / " + amountOfPods : amountOfPods} ${pluralize('pod', amountOfPods)} in ${pluralize('namespace', uniqueNamespaces.length)} ${uniqueNamespaces.join(", ")}`} {`Tapping ${amountOfUntappedPods > 0 ? amountOfTappedPods + " / " + amountOfPods : amountOfPods} ${pluralize('pod', amountOfPods)} in ${pluralize('namespace', uniqueNamespaces.length)} ${uniqueNamespaces.join(", ")}`}
</span> </span>
</div> </div>

View File

@ -18,7 +18,9 @@ const useWS = (wsUrl: string) => {
const onMessage = (e) => { setMessage(e) } const onMessage = (e) => { setMessage(e) }
const onError = (e) => setError(e) const onError = (e) => setError(e)
const onOpen = () => { setisOpen(true) } const onOpen = () => { setisOpen(true) }
const onClose = () => setisOpen(false) const onClose = () => {
setisOpen(false)
}
const openSocket = () => { const openSocket = () => {
ws.current = new WebSocket(wsUrl) ws.current = new WebSocket(wsUrl)
@ -36,13 +38,17 @@ const useWS = (wsUrl: string) => {
ws.current.removeEventListener("close", onClose) ws.current.removeEventListener("close", onClose)
} }
const sendQuery = (query: string) => { const sendQueryWhenWsOpen = (query) => {
if (ws.current && (ws.current.readyState === WebSocketReadyState.OPEN)) { setTimeout(() => {
ws.current.send(JSON.stringify({ "query": query, "enableFullEntries": false })); if (ws?.current?.readyState === WebSocket.OPEN) {
} ws.current.send(JSON.stringify({"query": query, "enableFullEntries": false}));
} else {
sendQueryWhenWsOpen(query);
}
}, 500)
} }
return { message, error, isOpen, openSocket, closeSocket, sendQuery } return { message, error, isOpen, openSocket, closeSocket, sendQueryWhenWsOpen }
} }
export default useWS export default useWS

View File

@ -13,7 +13,7 @@
"@types/jest": "^26.0.22", "@types/jest": "^26.0.22",
"@types/node": "^12.20.10", "@types/node": "^12.20.10",
"@uiw/react-textarea-code-editor": "^1.4.12", "@uiw/react-textarea-code-editor": "^1.4.12",
"@up9/mizu-common": "1.0.125", "@up9/mizu-common": "^1.0.128",
"axios": "^0.25.0", "axios": "^0.25.0",
"core-js": "^3.20.2", "core-js": "^3.20.2",
"craco-babel-loader": "^1.0.3", "craco-babel-loader": "^1.0.3",

View File

@ -1,11 +1,11 @@
import React, { useEffect } from "react"; import React, {useEffect} from "react";
import { Button } from "@material-ui/core"; import { Button } from "@material-ui/core";
import Api, {getWebsocketUrl} from "../../../helpers/api"; import Api,{getWebsocketUrl} from "../../../helpers/api";
import debounce from 'lodash/debounce'; import debounce from 'lodash/debounce';
import {useSetRecoilState, useRecoilState} from "recoil"; import {useSetRecoilState, useRecoilState} from "recoil";
import {useCommonStyles} from "../../../helpers/commonStyle" import {useCommonStyles} from "../../../helpers/commonStyle"
import serviceMapModalOpenAtom from "../../../recoil/serviceMapModalOpen"; import serviceMapModalOpenAtom from "../../../recoil/serviceMapModalOpen";
import TrafficViewer ,{useWS,DEFAULT_QUERY} from "@up9/mizu-common" import TrafficViewer from "@up9/mizu-common"
import "@up9/mizu-common/dist/index.css" import "@up9/mizu-common/dist/index.css"
import oasModalOpenAtom from "../../../recoil/oasModalOpen/atom"; import oasModalOpenAtom from "../../../recoil/oasModalOpen/atom";
import serviceMap from "../../assets/serviceMap.svg"; import serviceMap from "../../assets/serviceMap.svg";
@ -22,11 +22,10 @@ export const TrafficPage: React.FC<TrafficPageProps> = ({setAnalyzeStatus}) => {
const setServiceMapModalOpen = useSetRecoilState(serviceMapModalOpenAtom); const setServiceMapModalOpen = useSetRecoilState(serviceMapModalOpenAtom);
const [openOasModal, setOpenOasModal] = useRecoilState(oasModalOpenAtom); const [openOasModal, setOpenOasModal] = useRecoilState(oasModalOpenAtom);
const {message,error,isOpen, openSocket, closeSocket, sendQuery} = useWS(getWebsocketUrl()) const trafficViewerApi = {...api}
const trafficViewerApi = {...api, webSocket:{open : openSocket, close: closeSocket, sendQuery: sendQuery}}
const handleOpenOasModal = () => { const handleOpenOasModal = () => {
closeSocket() //closeSocket() -- Todo: Add Close webSocket
setOpenOasModal(true); setOpenOasModal(true);
} }
@ -56,18 +55,16 @@ export const TrafficPage: React.FC<TrafficPageProps> = ({setAnalyzeStatus}) => {
</Button>} </Button>}
</div> </div>
sendQuery(DEFAULT_QUERY);
useEffect(() => { useEffect(() => {
return () => { return () => {
closeSocket() //closeSocket()
} }
},[]) },[])
return ( return (
<> <>
<TrafficViewer setAnalyzeStatus={setAnalyzeStatus} message={message} error={error} isWebSocketOpen={isOpen} <TrafficViewer setAnalyzeStatus={setAnalyzeStatus} webSocketUrl={getWebsocketUrl()}
trafficViewerApiProp={trafficViewerApi} actionButtons={actionButtons} isShowStatusBar={!openOasModal}/> trafficViewerApiProp={trafficViewerApi} actionButtons={actionButtons} isShowStatusBar={!openOasModal}/>
</> </>
); );
}; };