Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds integration tests to client website #863

Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
13cf114
Add Library.test.tsx
atomicgamedeveloper Jul 2, 2024
bb6fa7c
Add test for tabs, their paragraphs, iframe, header and footer
atomicgamedeveloper Jul 5, 2024
cb30223
Add integration test for clicking tabs effect
atomicgamedeveloper Jul 8, 2024
b1b92af
Fix typo in Library common scope tab paragraph
atomicgamedeveloper Jul 8, 2024
72bbff7
Refactor and add scope tab tests
atomicgamedeveloper Jul 8, 2024
a57a3e2
Format and add test for selection attribute
atomicgamedeveloper Jul 8, 2024
9516391
Refactor and add new tab clicking tests
atomicgamedeveloper Jul 11, 2024
ffbd740
Fix broken tests
atomicgamedeveloper Jul 11, 2024
e2ebe8e
Merge branch 'INTO-CPS-Association:feature/distributed-demo' into 826…
atomicgamedeveloper Jul 11, 2024
7b0a990
Fix git actions
atomicgamedeveloper Jul 11, 2024
89fd0cf
Add DigitalTwins.test.tsx
atomicgamedeveloper Jul 12, 2024
d93f370
Add Workbench.test.tsx, utility functions and refactor
atomicgamedeveloper Jul 12, 2024
6d9f5ac
Fix git actions, map to forEach
atomicgamedeveloper Jul 12, 2024
877cc7b
Add integrationTestUtils.tsx
atomicgamedeveloper Jul 12, 2024
5f8bb5d
Add Menu.test.tsx unit test stump
atomicgamedeveloper Jul 15, 2024
f214efb
Add more utility functions and test more Layout components
atomicgamedeveloper Jul 16, 2024
15a5fd8
Fix eslint no-explicit-any issue
atomicgamedeveloper Jul 16, 2024
11438d6
Test Layout with Menu in all pages
atomicgamedeveloper Jul 16, 2024
b53e7a7
Fix formatting
atomicgamedeveloper Jul 16, 2024
99dd8e2
Rename variables, add more toolbar tests and refactor
atomicgamedeveloper Jul 18, 2024
ec9beea
Refactor duplicate beforeEach setup
atomicgamedeveloper Jul 18, 2024
ac58843
Add int global mocks and render tests with store
atomicgamedeveloper Jul 23, 2024
d85ec66
Use userEvent, add open-and-close drawer tests with click
atomicgamedeveloper Jul 23, 2024
5818d9b
Attach popper elements to root
atomicgamedeveloper Jul 23, 2024
1853d66
Remove failing assertion
atomicgamedeveloper Jul 24, 2024
e489375
Use React Testing Library act
atomicgamedeveloper Jul 24, 2024
8b9c6bc
Add tests for hovering tool tips and interacting with menu
atomicgamedeveloper Jul 24, 2024
d62a857
Test Workbench with icons, improve Layout tests
atomicgamedeveloper Jul 25, 2024
b0b8c13
Refactor Layout tests
atomicgamedeveloper Jul 25, 2024
4364564
Add integration tests for Account page
atomicgamedeveloper Jul 26, 2024
2dda92f
Render integration tests with router
atomicgamedeveloper Jul 29, 2024
51e7518
Structurize, add and improve integration tests and simplify jest configs
atomicgamedeveloper Aug 2, 2024
54607c7
Fix name and import inconsistencies
atomicgamedeveloper Aug 2, 2024
5ef015e
Remove layout.testUtil.tsx and refactor testSettingsButton
atomicgamedeveloper Aug 2, 2024
8ec02a1
Extend timeout to 15s
atomicgamedeveloper Aug 7, 2024
a605bee
Increment client/package.json version
atomicgamedeveloper Aug 7, 2024
0c78ccb
Refactor timeout to jest.json
atomicgamedeveloper Aug 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 25 additions & 7 deletions client/jest.config.json
prasadtalasila marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,32 @@
"transform": {
"^.+\\.tsx?$": "ts-jest"
},
"transformIgnorePatterns": ["/node_modules/(?![d3-shape|recharts]).+\\.js$"],
"transformIgnorePatterns": [
"/node_modules/(?![d3-shape|recharts]).+\\.js$"
],
"collectCoverage": true,
"coverageReporters": ["text", "cobertura", "clover", "lcov", "json"],
"collectCoverageFrom": ["src/**/*.{ts,tsx}"],
"coverageReporters": [
"text",
"cobertura",
"clover",
"lcov",
"json"
],
"collectCoverageFrom": [
"src/**/*.{ts,tsx}"
],
"coveragePathIgnorePatterns": [
"node_modules",
"build",
"src/index.tsx",
"src/AppProvider.tsx",
"src/store/store.ts"
],
"modulePathIgnorePatterns": ["test/e2e", "mocks", "config"],
"modulePathIgnorePatterns": [
"test/e2e",
"mocks",
"config"
],
"coverageDirectory": "<rootDir>/coverage/",
"coverageThreshold": {
"global": {
Expand All @@ -31,6 +45,10 @@
},
"verbose": true,
"testRegex": "/test/.*\\.test.tsx?$",
"modulePaths": ["<rootDir>/src/"],
"setupFilesAfterEnv": ["<rootDir>/test/unitTests/jest.setup.ts"]
}
"modulePaths": [
"<rootDir>/src/"
],
"setupFilesAfterEnv": [
"<rootDir>/test/unitTests/jest.setup.ts"
]
}
73 changes: 45 additions & 28 deletions client/jest.integration.config.json
prasadtalasila marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,29 +1,46 @@
{
"preset": "ts-jest",
"testEnvironment": "jsdom",
"transform": {
"^.+\\.tsx?$": "ts-jest"
},
"transformIgnorePatterns": ["/node_modules/(?![d3-shape|recharts]).+\\.js$"],
"collectCoverage": false,
"coverageReporters": ["text", "cobertura", "clover", "lcov", "json"],
"collectCoverageFrom": ["src/**/*.{ts,tsx}"],
"coveragePathIgnorePatterns": [
"node_modules",
"build",
"src/index.tsx",
"src/AppProvider.tsx",
"src/store/store.ts"
],
"modulePathIgnorePatterns": ["test/e2e", "mocks", "config"],
"coverageDirectory": "<rootDir>/coverage/",
"globals": {
"window.ENV.SERVER_HOSTNAME": "localhost",
"window.ENV.SERVER_PORT": 3500
},
"verbose": true,
"testRegex": "/test/.*\\.test.tsx?$",
"modulePaths": ["<rootDir>/src/"],
"setupFilesAfterEnv": ["<rootDir>/test/unitTests/jest.setup.ts"]
}

"preset": "ts-jest",
"testEnvironment": "jsdom",
"transform": {
"^.+\\.tsx?$": "ts-jest"
},
"transformIgnorePatterns": [
"/node_modules/(?![d3-shape|recharts]).+\\.js$"
],
"collectCoverage": false,
"coverageReporters": [
"text",
"cobertura",
"clover",
"lcov",
"json"
],
"collectCoverageFrom": [
"src/**/*.{ts,tsx}"
],
"coveragePathIgnorePatterns": [
"node_modules",
"build",
"src/index.tsx",
"src/AppProvider.tsx",
"src/store/store.ts"
],
"modulePathIgnorePatterns": [
"test/e2e",
"mocks",
"config"
],
"coverageDirectory": "<rootDir>/coverage/",
"globals": {
"window.ENV.SERVER_HOSTNAME": "localhost",
"window.ENV.SERVER_PORT": 3500
},
"verbose": true,
"testRegex": "/test/.*\\.test.tsx?$",
"modulePaths": [
"<rootDir>/src/"
],
"setupFilesAfterEnv": [
"<rootDir>/test/integration/jest.setup.ts"
]
}
7 changes: 6 additions & 1 deletion client/src/components/LinkButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,19 @@ interface LinkButtonProps {
* <LinkButtons buttons={linkValues} size={6} />
*/ const LinkButtons = ({ buttons, size, marginRight }: LinkButtonProps) => {
const iconButtons = getIconButtons(buttons);
const root = document.getElementById('root');
return (
<ButtonRow>
{iconButtons.map((button, index) => (
<div
key={index}
style={{ marginRight: marginRight ? `${marginRight}px` : '0px' }}
>
<Tooltip key={index} title={button.link}>
<Tooltip
key={index}
title={button.link}
PopperProps={{ container: root }}
>
<IconLabel>
<IconButton
onClick={() => {
Expand Down
6 changes: 3 additions & 3 deletions client/src/page/DrawerComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import { transition } from './MenuToolbar';
import MenuItems from './MenuItems';
import DrawerHeaderComponent from './DrawerHeaderComponent';

const drawerWidth = 240;
const drawerwidth = 240;
prasadtalasila marked this conversation as resolved.
Show resolved Hide resolved

const openedMixin = (theme: Theme): CSSObject => ({
width: drawerWidth,
width: drawerwidth,
transition: transition({ theme, open: true }),
overflowX: 'hidden',
});
Expand All @@ -27,7 +27,7 @@ const closedMixin = (theme: Theme): CSSObject => ({
const Drawer = styled(MuiDrawer, {
shouldForwardProp: (prop) => prop !== 'open',
})(({ theme, open }) => ({
width: drawerWidth,
width: drawerwidth,
flexShrink: 0,
whiteSpace: 'nowrap',
boxSizing: 'border-box',
Expand Down
4 changes: 2 additions & 2 deletions client/src/page/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { RootState } from 'store/store';
import MenuToolbar from './MenuToolbar';
import DrawerComponent from './DrawerComponent';

const drawerWidth = 240;
const drawerwidth = 240;

const hooks = () => {
const theme = useTheme();
Expand All @@ -29,7 +29,7 @@ function MiniDrawer() {
<Box sx={{ display: 'flex' }}>
<MenuToolbar
open={menuState.isOpen}
drawerWidth={drawerWidth}
drawerwidth={drawerwidth}
handleCloseUserMenu={handleCloseUserMenu}
handleDrawerOpen={handleDrawerOpen}
handleOpenUserMenu={handleOpenUserMenu}
Expand Down
19 changes: 10 additions & 9 deletions client/src/page/MenuToolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { signOut } from '../util/auth/Authentication';

interface AppBarProps extends MuiAppBarProps {
open?: boolean;
drawerWidth: number;
drawerwidth: number;
}

const transition = ({
Expand All @@ -36,12 +36,12 @@ const transition = ({

const AppBar = styled(MuiAppBar, {
shouldForwardProp: (prop) => prop !== 'open',
})<AppBarProps>(({ theme, open, drawerWidth }) => ({
})<AppBarProps>(({ theme, open, drawerwidth }) => ({
zIndex: theme.zIndex.drawer + 1,
transition: transition({ theme, open }),
...(open && {
marginLeft: drawerWidth,
width: `calc(100% - ${drawerWidth}px)`,
marginLeft: drawerwidth,
width: `calc(100% - ${drawerwidth}px)`,
transition: transition({ theme, open }),
}),
}));
Expand All @@ -51,28 +51,28 @@ interface MenuToolbarProps {
handleDrawerOpen: () => void;
handleOpenUserMenu: (event: React.MouseEvent<HTMLButtonElement>) => void;
handleCloseUserMenu: () => void;
drawerWidth: number;
drawerwidth: number;
anchorElUser: HTMLElement | null;
}

function MenuToolbar({
open,
drawerWidth,
drawerwidth,
handleCloseUserMenu,
handleOpenUserMenu,
handleDrawerOpen,
anchorElUser,
}: MenuToolbarProps) {
const auth = useAuth();
const root = document.getElementById('root');

const handleSignOut = async () => {
if (auth) {
await signOut(auth);
}
};

return (
<AppBar position="fixed" open={open} drawerWidth={drawerWidth}>
<AppBar position="fixed" open={open} drawerwidth={drawerwidth}>
<Toolbar sx={{ display: 'flex', justifyContent: 'space-between' }}>
<IconButton
color="inherit"
Expand All @@ -92,7 +92,7 @@ function MenuToolbar({

<Box sx={{ display: 'flex', alignItems: 'center', flexGrow: 0 }}>
<LinkButtons buttons={toolbarLinkValues} size={2.5} />
<Tooltip title="Open settings">
<Tooltip title="Open settings" PopperProps={{ container: root }}>
<IconButton onClick={handleOpenUserMenu}>
<Avatar sx={{ bgcolor: deepPurple[500] }}>A</Avatar>
</IconButton>
Expand All @@ -103,6 +103,7 @@ function MenuToolbar({
anchorEl={anchorElUser}
anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
keepMounted
container={root}
transformOrigin={{ vertical: 'top', horizontal: 'right' }}
open={Boolean(anchorElUser)}
onClose={handleCloseUserMenu}
Expand Down
2 changes: 1 addition & 1 deletion client/src/route/library/LibraryTabData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,6 @@ export const scope: ITabs[] = [
},
{
label: 'Common',
body: `These reusable assets are only visible to all users. Other users can use these assets in their digital twins.`,
body: `These reusable assets are visible to all users. Other users can use these assets in their digital twins.`,
},
];
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,24 @@ import * as React from 'react';
import { createStore } from 'redux';
import { screen } from '@testing-library/react';
import { useAuth } from 'react-oidc-context';
import PrivateRoute from '../../src/route/auth/PrivateRoute';
import Library from '../../src/route/library/Library';
import authReducer from '../../src/store/auth.slice';
import { renderWithRouter } from '../unitTests/testUtils';
import PrivateRoute from 'route/auth/PrivateRoute';
import Library from 'route/library/Library';
import authReducer from 'store/auth.slice';
import { renderWithRouter } from '../../unitTests/testUtils';
import { userMock } from '../../unitTests/__mocks__/global_mocks';

jest.mock('react-oidc-context', () => ({
useAuth: jest.fn(),
jest.mock('util/auth/Authentication', () => ({
getAndSetUsername: jest.fn(),
}));

jest.mock('react-redux', () => ({
...jest.requireActual('react-redux'),
useDispatch: jest.fn(),
}));

jest.mock('../../src/util/auth/Authentication', () => ({
getAndSetUsername: jest.fn(),
jest.mock('page/Menu', () => ({
__esModule: true,
default: () => <div data-testid="menu" />,
}));

const store = createStore(authReducer);
Expand All @@ -27,13 +29,6 @@ type AuthState = {
};

const setupTest = (authState: AuthState) => {
const userMock = {
profile: {
profile: 'example/username',
},
access_token: 'example_token',
};

(useAuth as jest.Mock).mockReturnValue({ ...authState, user: userMock });

if (authState.isAuthenticated) {
Expand Down
68 changes: 68 additions & 0 deletions client/test/integration/Routes/DigitalTwins.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import * as React from 'react';
import { screen, within } from '@testing-library/react';
import tabs from 'route/digitaltwins/DigitalTwinTabData';
import DigitalTwins from 'route/digitaltwins/DigitalTwins';
import userEvent from '@testing-library/user-event';
import {
closestDiv,
itShowsTheParagraphOfToTheSelectedTab,
normalizer,
setupIntegrationTest,
testLayout,
} from '../integrationTestUtils';

const setup = () => setupIntegrationTest(<DigitalTwins />);

describe('Digital Twins', () => {
beforeEach(() => {
setup();
});

it('renders the Digital Twins page and Layout correctly', async () => {
await testLayout();

const tablists = screen.getAllByRole('tablist');
expect(tablists).toHaveLength(2);

// The div of the Digital Twins (Create, Execute and Analyze) tabs
const mainTabsDiv = closestDiv(tablists[0]);
const mainTablist = within(mainTabsDiv).getAllByRole('tablist')[0];
const mainTabs = within(mainTablist).getAllByRole('tab');
expect(mainTabs).toHaveLength(3);

mainTabs.forEach((tab, tabIndex) => {
expect(tab).toHaveTextContent(tabs[tabIndex].label);
});

const mainParagraph = screen.getByText(tabs[0].body, { normalizer });
expect(mainParagraph).toBeInTheDocument();

const mainParagraphDiv = closestDiv(mainParagraph);
const iframe = within(mainParagraphDiv).getByTitle(
/JupyterLight-Demo-Create/i,
);
expect(iframe).toBeInTheDocument();
expect(iframe).toHaveProperty('src', 'https://example.com/URL_DT');
}, 7000);

it('shows the paragraph of to the selected tab', async () => {
await itShowsTheParagraphOfToTheSelectedTab([tabs]);
});

/* eslint-disable no-await-in-loop */
it('changes iframe src according to the selected tab', async () => {
for (let tabsIndex = 0; tabsIndex < tabs.length; tabsIndex += 1) {
const tabsData = tabs[tabsIndex];
const isFirstTab = tabsIndex === 0;
const tab = screen.getByRole('tab', {
name: tabsData.label,
selected: isFirstTab,
});
await userEvent.click(tab);
const iframe = screen.getByTitle(`JupyterLight-Demo-${tabsData.label}`);
expect(iframe).toBeInTheDocument();
expect(iframe).toHaveProperty('src', `https://example.com/URL_DT`);
}
});
/* eslint-enable no-await-in-loop */
});
Loading
Loading