Skip to content

Commit

Permalink
✨ 374 New File Names (#382)
Browse files Browse the repository at this point in the history
  • Loading branch information
xoscar committed Apr 29, 2022
1 parent d95f3e0 commit 03e78e0
Show file tree
Hide file tree
Showing 70 changed files with 599 additions and 545 deletions.
58 changes: 51 additions & 7 deletions docs/development.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,74 @@
# Development
# Development Guide

## **Web Folder Structure**
The phiolosphy used to build the frontend is based on object composition and functional programming principles, as well as following the idea of "code that is updated together should be together" as much as we can. To achieve this the main funcionality is divided into the following concepts:

### **Web Folder Tree**
**Gateways**
Interfaces to the outbound backend services and the browser.
Used by Components, Services.

**Models**
Encapsulate a set of attributes and modules.
Used by Services, APIs.

**Services**
Define and drive the Business logic functionality
Used by Components, Selectors.

**Factories**
Component Facades that allow rendering different versions depending on the use case.
Used by Components.

**Selectors**
Parse, aggregate and clean data across the app.
Used by Components.

### Styling Framework
For styling and web components the main framework in use is [Ant Design](https://ant.design/).

### Web Folder Structure

#### Web Folder Tree

- [public/](./web/public)
- [src/](./web/src)
- [components/](./web/src/components)
- [gateways/](./web/src/gateways)
- [assets/](./web/src/assets)
- [hooks/](./web/src/hooks)
- [lib/](./web/src/lib)
- [constants/](./web/src/lib)
- [entities/](./web/src/entities/)
- [navigation/](./web/src/navigation)
- [pages/](./web/src/pages)
- [redux/](./web/src/redux)
- [services/](./web/src/services)
- [types/](./web/src/types)
- [utils/](./web/src/utils)

| Folder | Description |
| ----------- | ---------------------------------------------------------------------- |
| public/ | contains html and can put any scripts, or static files |
| assets/ | contains icons, images or any other private non-code file used in the app |
| gateways/ | any API connector |
| components/ | any reusable components |
| hooks/ | any reusable hooks |
| lib/ | any constants |
| constants/ | any constants |
| navigation/ | react-router setup |
| pages/ | each page has its folder that contains styled file, and sub components |
| redux/ | state management setup |
| services/ | any class or functions that talk with data and processing it |
| entities/ | each entity from the application has its own folder containing services, models, gateways, etc |
| types/ | defined models used in the web app |
| utils/ | any pure functions that shared in the app |

#### File Types

| Type | Exstension | Example
| ----------- | ----------------------- | ----
| Service | .service.ts | Span.service.ts
| Model | .model.ts | Span.model.ts
| Factory | .factory.tsx | Diagram.factory.tsx
| Component | .tsx | Input.tsx
| Styled Components | .styled.ts(x) | HomePage.styled.ts
| Selectors | .selectors.ts | Span.selectors.ts
| Gateways | .gateway.ts | TestApi.gateway.ts
| Test | .test.ts | Span.test.ts|
| Constants | .constants.ts | Trace.constants.ts
| Types | .types.ts | Assertion.types.ts
2 changes: 1 addition & 1 deletion web/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {Provider} from 'react-redux';
import {TourProvider} from '@reactour/tour';
import Router from './navigation';
import Router from './components/Navigation';
import {store} from './redux/store';
import './App.css';
import AnalyticsProvider from './components/Analytics/AnalyticsProvider';
Expand Down
2 changes: 1 addition & 1 deletion web/src/components/Analytics/AnalyticsProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {ReactElement, useEffect, useState, createContext, useCallback, useMemo} from 'react';
import {isEnabled, instance} from '../../services/analytics/AnalyticsService';
import {isEnabled, instance} from '../../services/Analytics/Analytics.service';

export const Context = createContext({
isEnabled,
Expand Down
2 changes: 1 addition & 1 deletion web/src/components/Analytics/useAnalytics.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {useContext, useMemo} from 'react';
import {GA4ReactInterface} from 'ga-4-react/src/models/gtagModels';
import {Context} from './AnalyticsProvider';
import AnalyticsService, {Categories} from '../../services/analytics/AnalyticsService';
import AnalyticsService, {Categories} from '../../services/Analytics/Analytics.service';

export type TAnalyticsService<A> = {
isEnabled: boolean;
Expand Down
33 changes: 20 additions & 13 deletions web/src/components/AssertionsTable/AssertionsTable.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,33 @@
import {Button, Table, Typography} from 'antd';
import {useMemo, useState} from 'react';
import {Assertion, SpanAssertionResult, ITrace, ISpan} from 'types';
import {getOperator} from 'utils';
import AssertionTableAnalyticsService from '../../services/Analytics/AssertionTableAnalytics.service';
import {IAssertion, ISpanAssertionResult} from '../../types/Assertion.types';
import OperatorService from '../../services/Operator.service';
import {ISpan} from '../../types/Span.types';
import {ITrace} from '../../types/Trace.types';
import CreateAssertionModal from '../CreateAssertionModal';
import CustomTable from '../CustomTable';
import * as S from './AssertionsTable.styled';
import AssertionTableAnalyticsService from '../../services/analytics/AssertionTableAnalyticsService';

type AssertionsResultTableProps = {
assertionResults: SpanAssertionResult[];
assertion: Assertion;
interface IAssertionsResultTableProps {
assertionResults: ISpanAssertionResult[];
assertion: IAssertion;
sort: number;
span: ISpan;
testId: string;
trace: ITrace;
};
}

type TParsedAssertion = {
interface IParsedAssertion {
key: string;
property: string;
comparison: string;
value: string;
actualValue: string;
hasPassed: boolean;
};
}

const AssertionsResultTable: React.FC<AssertionsResultTableProps> = ({
const AssertionsResultTable: React.FC<IAssertionsResultTableProps> = ({
assertionResults,
assertion: {selectors = []},
assertion,
Expand All @@ -36,7 +38,7 @@ const AssertionsResultTable: React.FC<AssertionsResultTableProps> = ({
}) => {
const [isModalOpen, setIsModalOpen] = useState(false);

const parsedAssertionList = useMemo<Array<TParsedAssertion>>(
const parsedAssertionList = useMemo<Array<IParsedAssertion>>(
() =>
assertionResults.map(({propertyName, comparisonValue, operator, actualValue, hasPassed}) => ({
key: propertyName,
Expand Down Expand Up @@ -70,13 +72,18 @@ const AssertionsResultTable: React.FC<AssertionsResultTableProps> = ({
</S.AssertionsTableHeader>
<CustomTable size="small" pagination={{hideOnSinglePage: true}} dataSource={parsedAssertionList}>
<Table.Column title="Property" dataIndex="property" key="property" ellipsis width="50%" />
<Table.Column title="Comparison" dataIndex="comparison" key="comparison" render={value => getOperator(value)} />
<Table.Column
title="Comparison"
dataIndex="comparison"
key="comparison"
render={value => OperatorService.getOperatorName(value)}
/>
<Table.Column title="Value" dataIndex="value" key="value" />
<Table.Column
title="Actual"
dataIndex="actualValue"
key="actualValue"
render={(value, record: TParsedAssertion) => (
render={(value, record: IParsedAssertion) => (
<Typography.Text strong type={record.hasPassed ? 'success' : 'danger'}>
{value}
</Typography.Text>
Expand Down
60 changes: 32 additions & 28 deletions web/src/components/CreateAssertionModal/CreateAssertionForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,22 @@ import {QuestionCircleOutlined, PlusOutlined, MinusCircleOutlined} from '@ant-de
import {Button, Input, AutoComplete, Typography, Tooltip, Form, Space, FormInstance} from 'antd';
import jemsPath from 'jmespath';

import {Assertion, COMPARE_OPERATOR, ISpan, ItemSelector, ITrace, LOCATION_NAME, SpanSelector} from 'types';
import {useCreateAssertionMutation, useUpdateAssertionMutation} from 'redux/services/TestService';
import {SELECTOR_DEFAULT_ATTRIBUTES} from 'lib/SelectorDefaultAttributes';
import {filterBySpanId} from 'utils';
import {getSpanSignature} from 'services/SpanService';
import {getSpanAttributeValueType} from 'services/SpanAttributeService';
import GuidedTourService, {GuidedTours} from 'services/GuidedTourService';
import {Steps} from 'components/GuidedTour/assertionStepList';
import {useCreateAssertionMutation, useUpdateAssertionMutation} from 'gateways/Test.gateway';
import {SELECTOR_DEFAULT_ATTRIBUTES} from 'constants/SemanticGroupNames.constants';
import {filterBySpanId} from 'utils/Common';
import {getSpanSignature} from 'services/Span.service';
import {getSpanAttributeValueType} from 'services/SpansAttribute.service';
import GuidedTourService, {GuidedTours} from 'services/GuidedTour.service';
import useGuidedTour from 'hooks/useGuidedTour';
import {CreateAssertionSelectorInput} from './CreateAssertionSelectorInput';
import * as S from './CreateAssertionModal.styled';
import CreateAssertionModalAnalyticsService from '../../services/analytics/CreateAssertionModalAnalyticsService';
import CreateAssertionModalAnalyticsService from '../../services/Analytics/CreateAssertionModalAnalytics.service';
import {IAssertion, IItemSelector, ISpanSelector} from '../../types/Assertion.types';
import { CompareOperator } from '../../constants/Operator.constants';
import { ISpan } from '../../types/Span.types';
import { ITrace } from '../../types/Trace.types';
import { LOCATION_NAME } from '../../constants/Span.constants';
import { Steps } from '../GuidedTour/assertionStepList';

const {
onAddCheck,
Expand All @@ -26,27 +30,27 @@ const {
onSelectorChange,
} = CreateAssertionModalAnalyticsService;

interface AssertionSpan {
interface IAssertionSpan {
key: string;
compareOp: keyof typeof COMPARE_OPERATOR;
compareOp: CompareOperator;
value: string;
}
};

export type TValues = {
assertionList: AssertionSpan[];
selectorList: ItemSelector[];
assertionList: IAssertionSpan[];
selectorList: IItemSelector[];
};

const itemSelectorKeys = SELECTOR_DEFAULT_ATTRIBUTES.map(el => el.attributes).flat();

interface TCreateAssertionFormProps {
onCreate(): void;
onForm(form: FormInstance): void;
onSelectorList(selectorList: ItemSelector[]): void;
onSelectorList(selectorList: IItemSelector[]): void;
span: ISpan;
testId: string;
trace: ITrace;
assertion?: Assertion;
assertion?: IAssertion;
}

const CreateAssertionForm: React.FC<TCreateAssertionFormProps> = ({
Expand All @@ -66,7 +70,7 @@ const CreateAssertionForm: React.FC<TCreateAssertionFormProps> = ({

useGuidedTour(GuidedTours.Assertion);

const defaultAssertionList = useMemo<AssertionSpan[]>(() => {
const defaultAssertionList = useMemo<IAssertionSpan[]>(() => {
if (assertion) {
return assertion.spanAssertions?.map(({propertyName, operator, comparisonValue}) => ({
key: propertyName,
Expand All @@ -78,7 +82,7 @@ const CreateAssertionForm: React.FC<TCreateAssertionFormProps> = ({
return [
{
key: '',
compareOp: COMPARE_OPERATOR.EQUALS,
compareOp: CompareOperator.EQUALS,
value: '',
},
];
Expand Down Expand Up @@ -149,7 +153,7 @@ const CreateAssertionForm: React.FC<TCreateAssertionFormProps> = ({
valueType: getSpanAttributeValueType(spanAttribute!),
};
})
.filter((el): el is SpanSelector => Boolean(el));
.filter((el): el is ISpanSelector => Boolean(el));

const newData = {selectors: selectorList, spanAssertions};

Expand Down Expand Up @@ -188,7 +192,7 @@ const CreateAssertionForm: React.FC<TCreateAssertionFormProps> = ({
if (fieldName === 'assertionList') onChecksChange(JSON.stringify(form.getFieldValue('assertionList') || []));

if (fieldName === 'assertionList' && keyName === 'key' && field.value) {
const assertionList: AssertionSpan[] = form.getFieldValue('assertionList') || [];
const assertionList: IAssertionSpan[] = form.getFieldValue('assertionList') || [];

form.setFieldsValue({
assertionList: assertionList.map((assertionEntry, index) => {
Expand Down Expand Up @@ -249,19 +253,19 @@ const CreateAssertionForm: React.FC<TCreateAssertionFormProps> = ({
</Form.Item>
<S.FullHeightFormItem
{...field}
initialValue={COMPARE_OPERATOR.EQUALS}
initialValue={CompareOperator.EQUALS}
style={{margin: 0}}
name={[name, 'compareOp']}
rules={[{required: true, message: 'Operator is required'}]}
>
<S.Select style={{margin: 0}}>
<S.Select.Option value={COMPARE_OPERATOR.EQUALS}>eq</S.Select.Option>
<S.Select.Option value={COMPARE_OPERATOR.NOTEQUALS}>ne</S.Select.Option>
<S.Select.Option value={COMPARE_OPERATOR.GREATERTHAN}>gt</S.Select.Option>
<S.Select.Option value={COMPARE_OPERATOR.LESSTHAN}>lt</S.Select.Option>
<S.Select.Option value={COMPARE_OPERATOR.GREATOREQUALS}>ge</S.Select.Option>
<S.Select.Option value={COMPARE_OPERATOR.LESSOREQUAL}>le</S.Select.Option>
<S.Select.Option value={COMPARE_OPERATOR.CONTAINS}>contains</S.Select.Option>
<S.Select.Option value={CompareOperator.EQUALS}>eq</S.Select.Option>
<S.Select.Option value={CompareOperator.NOTEQUALS}>ne</S.Select.Option>
<S.Select.Option value={CompareOperator.GREATERTHAN}>gt</S.Select.Option>
<S.Select.Option value={CompareOperator.LESSTHAN}>lt</S.Select.Option>
<S.Select.Option value={CompareOperator.GREATOREQUALS}>ge</S.Select.Option>
<S.Select.Option value={CompareOperator.LESSOREQUAL}>le</S.Select.Option>
<S.Select.Option value={CompareOperator.CONTAINS}>contains</S.Select.Option>
</S.Select>
</S.FullHeightFormItem>
<S.FullHeightFormItem
Expand Down
12 changes: 7 additions & 5 deletions web/src/components/CreateAssertionModal/CreateAssertionModal.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import {useCallback, useState} from 'react';
import {Modal, Typography, FormInstance} from 'antd';

import {Assertion, ISpan, ItemSelector, ITrace} from 'types';
import CreateAssertionForm, {TValues} from './CreateAssertionForm';
import {getEffectedSpansCount} from '../../services/AssertionService';
import {getEffectedSpansCount} from '../../services/Assertion.service';
import { ISpan } from '../../types/Span.types';
import { ITrace } from '../../types/Trace.types';
import { IAssertion, IItemSelector } from '../../types/Assertion.types';

interface IProps {
open: boolean;
onClose: () => void;
span: ISpan;
testId: string;
trace: ITrace;
assertion?: Assertion;
assertion?: IAssertion;
}

const effectedSpanMessage = (spanCount: number) => {
Expand All @@ -24,13 +26,13 @@ const effectedSpanMessage = (spanCount: number) => {

const CreateAssertionModal = ({testId, span, trace, open, onClose, assertion}: IProps) => {
const [form, setForm] = useState<FormInstance<TValues>>();
const [selectorList, setSelectorList] = useState<ItemSelector[]>([]);
const [selectorList, setSelectorList] = useState<IItemSelector[]>([]);

const onForm = useCallback((formInstance: FormInstance) => {
setForm(formInstance);
}, []);

const onSelectorList = useCallback((selectorListData: ItemSelector[]) => {
const onSelectorList = useCallback((selectorListData: IItemSelector[]) => {
setSelectorList(selectorListData);
}, []);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import {TagOutlined} from '@ant-design/icons';
import {AutoComplete, Checkbox, Input, Tag} from 'antd';
import {noop} from 'lodash';
import React, {useCallback, useMemo, useState} from 'react';
import {ItemSelector} from '../../types';
import { IItemSelector } from '../../types/Assertion.types';

type TItemSelectorDropdownProps = {
spanSignature: ItemSelector[];
value?: ItemSelector[];
onChange?(selectorList: ItemSelector[]): void;
spanSignature: IItemSelector[];
value?: IItemSelector[];
onChange?(selectorList: IItemSelector[]): void;
};

export const CreateAssertionSelectorInput: React.FC<TItemSelectorDropdownProps> = ({
Expand Down Expand Up @@ -52,7 +52,7 @@ export const CreateAssertionSelectorInput: React.FC<TItemSelectorDropdownProps>
);

const handleDeleteItemSelector = useCallback(
(item: ItemSelector) => {
(item: IItemSelector) => {
onChange(selectorList.filter(({propertyName}) => propertyName !== item.propertyName));
},
[onChange, selectorList]
Expand All @@ -61,7 +61,7 @@ export const CreateAssertionSelectorInput: React.FC<TItemSelectorDropdownProps>
return (
<>
<div style={{display: 'flex', flexWrap: 'wrap'}}>
{selectorList.map((item: ItemSelector) => (
{selectorList.map((item: IItemSelector) => (
<Tag
key={item.propertyName}
style={{marginBottom: 8}}
Expand Down
Loading

0 comments on commit 03e78e0

Please sign in to comment.