Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
8537384
implement precall test page, add unit tests, translations
behei-vonage Oct 14, 2025
da00e60
// eslint-disable-next-line @cspell/spellchecker
behei-vonage Oct 14, 2025
f8bb1d1
usenetwork tests
behei-vonage Oct 14, 2025
4612f06
landing.spec.ts
behei-vonage Oct 14, 2025
c925383
try again
behei-vonage Oct 14, 2025
57286c0
eslint
behei-vonage Oct 14, 2025
d2e8723
copy-pasta fix
behei-vonage Oct 14, 2025
9b69676
some cleanup
behei-vonage Oct 14, 2025
8c50349
let me push?
behei-vonage Oct 15, 2025
f2ae901
renaming
behei-vonage Oct 15, 2025
48768cd
some changes
behei-vonage Oct 15, 2025
167be97
ugh only
behei-vonage Oct 15, 2025
9d11a71
remove comments
behei-vonage Oct 16, 2025
eb4c64e
comments
behei-vonage Oct 16, 2025
122cc5b
some more renaming
behei-vonage Oct 16, 2025
281582c
alright redone?
behei-vonage Oct 16, 2025
29754c8
missed this one
behei-vonage Oct 16, 2025
b93ee6a
missed this
behei-vonage Oct 16, 2025
be78163
Commit screenshot file: integration-tests/tests/visualComparisons.spe…
github-actions[bot] Oct 16, 2025
6d111be
Commit screenshot file: integration-tests/tests/visualComparisons.spe…
github-actions[bot] Oct 16, 2025
bf1826f
Commit screenshot file: integration-tests/tests/visualComparisons.spe…
github-actions[bot] Oct 16, 2025
00619f6
Commit screenshot file: integration-tests/tests/visualComparisons.spe…
github-actions[bot] Oct 16, 2025
8158409
Commit screenshot file: integration-tests/tests/visualComparisons.spe…
github-actions[bot] Oct 16, 2025
bc50736
Commit screenshot file: integration-tests/tests/visualComparisons.spe…
github-actions[bot] Oct 16, 2025
e7d7dae
translate some
behei-vonage Oct 16, 2025
dd73b88
Merge branch 'behei-vonage/precall-testr' of github.com:Vonage/vonage…
behei-vonage Oct 16, 2025
5914c5c
one component mui-ed
behei-vonage Oct 16, 2025
53c1dd4
few more mui-ed
behei-vonage Oct 16, 2025
db0aacd
testprogress
behei-vonage Oct 16, 2025
c420ca2
mui one more thing
behei-vonage Oct 16, 2025
ec95dfb
removing console log
behei-vonage Oct 16, 2025
f611ca6
Update frontend/src/components/WaitingRoom/UserNameInput/UserNameInpu…
behei-vonage Oct 16, 2025
3c69431
some renaming and configurability
behei-vonage Oct 17, 2025
8b9998e
component rename and test
behei-vonage Oct 17, 2025
0b5eb19
change to mui
behei-vonage Oct 17, 2025
ce54f39
Commit screenshot file: integration-tests/tests/visualComparisons.spe…
github-actions[bot] Oct 17, 2025
7a70be4
Commit screenshot file: integration-tests/tests/visualComparisons.spe…
github-actions[bot] Oct 17, 2025
f464fa6
Commit screenshot file: integration-tests/tests/visualComparisons.spe…
github-actions[bot] Oct 17, 2025
b3483ff
Commit screenshot file: integration-tests/tests/visualComparisons.spe…
github-actions[bot] Oct 17, 2025
d4e6b65
Commit screenshot file: integration-tests/tests/visualComparisons.spe…
github-actions[bot] Oct 17, 2025
8a1f3e7
Commit screenshot file: integration-tests/tests/visualComparisons.spe…
github-actions[bot] Oct 17, 2025
e118703
Merge branch 'develop' into behei-vonage/precall-testr
behei-vonage Oct 22, 2025
2c96e14
comma comma comma comma
behei-vonage Oct 22, 2025
e14ec25
oh lord
behei-vonage Oct 31, 2025
5702a60
Commit screenshot file: integration-tests/tests/visualComparisons.spe…
github-actions[bot] Oct 31, 2025
293ece8
Commit screenshot file: integration-tests/tests/visualComparisons.spe…
github-actions[bot] Oct 31, 2025
4607d5d
Commit screenshot file: integration-tests/tests/visualComparisons.spe…
github-actions[bot] Oct 31, 2025
9dd0114
Commit screenshot file: integration-tests/tests/visualComparisons.spe…
github-actions[bot] Oct 31, 2025
4571e17
Commit screenshot file: integration-tests/tests/visualComparisons.spe…
github-actions[bot] Oct 31, 2025
25f711d
Commit screenshot file: integration-tests/tests/visualComparisons.spe…
github-actions[bot] Oct 31, 2025
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
1 change: 1 addition & 0 deletions customWordList.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ NOSONAR
jiraiOSComponentId
supportedLngs
applinks
precall
1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"i18next-browser-languagedetector": "^8.2.0",
"lodash": "^4.17.21",
"opentok-layout-js": "^5.4.0",
"@vonage/video-client-network-test": "^3.1.6",
"opentok-solutions-logging": "^1.1.5",
"postcss": "^8.4.38",
"react": "^19.1.0",
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import WaitingRoom from './pages/WaitingRoom';
import SessionProvider from './Context/SessionProvider/session';
import { PreviewPublisherProvider } from './Context/PreviewPublisherProvider';
import LandingPage from './pages/LandingPage';
import PreCallTest from './pages/PreCallTest';
import { PublisherProvider } from './Context/PublisherProvider';
import RedirectToWaitingRoom from './components/RedirectToWaitingRoom';
import UnsupportedBrowserPage from './pages/UnsupportedBrowserPage';
Expand Down Expand Up @@ -39,6 +40,7 @@ const App = () => {
/>
</Route>
<Route path="/goodbye" element={<GoodBye />} />
<Route path="/precall/:roomName" element={<PreCallTest />} />
<Route path="*" element={<LandingPage />} />
<Route path="/unsupported-browser" element={<UnsupportedBrowserPage />} />
</Routes>
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/JoinButton/JoinButton.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ describe('JoinButtonComponent', () => {

fireEvent.click(screen.getByRole('button'));

expect(mockNavigate).toHaveBeenCalledWith('/waiting-room/test-room');
expect(mockNavigate).toHaveBeenCalledWith('/precall/test-room');
});

it('should not navigate to the waiting room if the room name is empty', () => {
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/JoinButton/JoinButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const JoinButton = ({ roomName, isDisabled }: JoinButtonProps): ReactElement =>

const handleJoin = (event: MouseEvent) => {
event.preventDefault();
navigate(`/waiting-room/${roomName}`);
navigate(`/precall/${roomName}`);
};

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
import { render, screen } from '@testing-library/react';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import ConnectivityResults from './ConnectivityResults';
import { ConnectivityResults as ConnectivityResultsType } from '../../../hooks/useNetworkTest';
import enTranslations from '../../../locales/en.json';

// Mock react-i18next
vi.mock('react-i18next', () => ({
useTranslation: () => ({
t: (key: string) => {
const translations: Record<string, string> = {
'precallTest.connectivityResults': enTranslations['precallTest.connectivityResults'],
'precallTest.status': enTranslations['precallTest.status'],
'precallTest.success': enTranslations['precallTest.success'],
'precallTest.failed': enTranslations['precallTest.failed'],
'precallTest.issues': enTranslations['precallTest.issues'],
};
return translations[key] || key;
},
}),
}));

describe('ConnectivityResults', () => {
beforeEach(() => {
vi.clearAllMocks();
});

it('renders the connectivity results title', () => {
const mockResults: ConnectivityResultsType = {
success: true,
};

render(<ConnectivityResults results={mockResults} />);

expect(screen.getByText(enTranslations['precallTest.connectivityResults'])).toBeInTheDocument();
});

it('displays success status when connectivity test passes', () => {
const mockResults: ConnectivityResultsType = {
success: true,
};

render(<ConnectivityResults results={mockResults} />);

expect(
screen.getByText((content) => content.includes(enTranslations['precallTest.status']))
).toBeInTheDocument();
expect(
screen.getByText((content) => content.includes(enTranslations['precallTest.success']))
).toBeInTheDocument();
});

it('displays failed status when connectivity test fails', () => {
const mockResults: ConnectivityResultsType = {
success: false,
};

render(<ConnectivityResults results={mockResults} />);

expect(
screen.getByText((content) => content.includes(enTranslations['precallTest.status']))
).toBeInTheDocument();
expect(
screen.getByText((content) => content.includes(enTranslations['precallTest.failed']))
).toBeInTheDocument();
});

it('displays failed tests when failedTests array is provided', () => {
const mockResults: ConnectivityResultsType = {
success: false,
failedTests: [
{
type: 'ConnectToSession',
error: {
message: 'Failed to connect to session',
name: 'CONNECTION_ERROR',
},
},
{
type: 'PublishToSession',
error: {
message: 'Failed to publish stream',
name: 'PUBLISH_ERROR',
},
},
],
};

render(<ConnectivityResults results={mockResults} />);

expect(
screen.getByText((content) => content.includes(enTranslations['precallTest.issues']))
).toBeInTheDocument();
expect(screen.getByText('ConnectToSession: Failed to connect to session')).toBeInTheDocument();
expect(screen.getByText('PublishToSession: Failed to publish stream')).toBeInTheDocument();
});

it('does not display issues section when test is successful', () => {
const mockResults: ConnectivityResultsType = {
success: true,
};

render(<ConnectivityResults results={mockResults} />);

expect(screen.queryByText(enTranslations['precallTest.issues'])).not.toBeInTheDocument();
});

it('does not display issues section when failedTests array is empty', () => {
const mockResults: ConnectivityResultsType = {
success: false,
failedTests: [],
};

render(<ConnectivityResults results={mockResults} />);

expect(screen.queryByText(enTranslations['precallTest.issues'])).not.toBeInTheDocument();
});

it('handles single failed test correctly', () => {
const mockResults: ConnectivityResultsType = {
success: false,
failedTests: [
{
type: 'MediaAccess',
error: {
message: 'Camera access denied',
name: 'MEDIA_ACCESS_DENIED',
},
},
],
};

render(<ConnectivityResults results={mockResults} />);

expect(
screen.getByText((content) => content.includes(enTranslations['precallTest.issues']))
).toBeInTheDocument();
expect(screen.getByText('MediaAccess: Camera access denied')).toBeInTheDocument();
});

it('handles multiple failed tests with different error types', () => {
const mockResults: ConnectivityResultsType = {
success: false,
failedTests: [
{
type: 'NetworkLatency',
error: {
message: 'High network latency detected',
name: 'LATENCY_ERROR',
},
},
{
type: 'Bandwidth',
error: {
message: 'Insufficient bandwidth',
name: 'BANDWIDTH_ERROR',
},
},
{
type: 'FirewallBlocking',
error: {
message: 'Firewall blocking connection',
name: 'FIREWALL_ERROR',
},
},
],
};

render(<ConnectivityResults results={mockResults} />);

expect(
screen.getByText((content) => content.includes(enTranslations['precallTest.issues']))
).toBeInTheDocument();
expect(screen.getByText('NetworkLatency: High network latency detected')).toBeInTheDocument();
expect(screen.getByText('Bandwidth: Insufficient bandwidth')).toBeInTheDocument();
expect(screen.getByText('FirewallBlocking: Firewall blocking connection')).toBeInTheDocument();
});

it('renders failed status with issues when both conditions are met', () => {
const mockResults: ConnectivityResultsType = {
success: false,
failedTests: [
{
type: 'TestType',
error: {
message: 'Test error message',
name: 'TEST_ERROR',
},
},
],
};

render(<ConnectivityResults results={mockResults} />);

expect(
screen.getByText((content) => content.includes(enTranslations['precallTest.issues']))
).toBeInTheDocument();
expect(
screen.getByText((content) => content.includes(enTranslations['precallTest.failed']))
).toBeInTheDocument();
expect(screen.getByText('TestType: Test error message')).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { ReactElement } from 'react';
import { useTranslation } from 'react-i18next';
import { ConnectivityResults as ConnectivityResultsType } from '../../../hooks/useNetworkTest';

export type ConnectivityResultsProps = {
results: ConnectivityResultsType;
};

/**
* ConnectivityResults Component
*
* This component displays the results of the connectivity test.
* @param {ConnectivityResultsProps} props - The props for the component.
* @property {ConnectivityResultsType} results - The connectivity test results to display.
* @returns {ReactElement} The connectivity results component.
*/
const ConnectivityResults = ({ results }: ConnectivityResultsProps): ReactElement => {
const { t } = useTranslation();

return (
<div className="mb-6 rounded-lg border bg-white p-4 text-left">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: Could we take profit of MUI components instead of native HTML? MUI will be used to allow the user to use custom colors, so, using MUI components will make it much easier🙏
I can think of <h3> for example being replaced by something like this:

<Typography
  variant="h6" // corresponds roughly to <h3>
  className="mb-2 font-bold"
>
  Heading
</Typography>

Many of this component could be replaced by MUI components?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hey @OscarFava, I actually ended up getting rid off this file but I followed your suggestions in QualityResults component. Please let me know if it looks good to you and I'll change it in other places

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually, I went ahead and changed all of them to use MUI. let me know if you have any other concerns there 🙏

<h3 className="mb-2 font-bold">{t('precallTest.connectivityResults')}</h3>
<p>
{t('precallTest.status')}:{' '}
{results.success ? `✅ ${t('precallTest.success')}` : `❌ ${t('precallTest.failed')}`}
</p>
{results.failedTests && results.failedTests.length > 0 && (
<div className="mt-2">
<h4 className="font-semibold">{t('precallTest.issues')}:</h4>
{results.failedTests.map((test) => (
<div key={test.type} className="ml-4 text-sm">
<p>
{test.type}: {test.error.message}
</p>
</div>
))}
</div>
)}
</div>
);
};

export default ConnectivityResults;
3 changes: 3 additions & 0 deletions frontend/src/components/PreCall/ConnectivityResults/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import ConnectivityResults from './ConnectivityResults';

export default ConnectivityResults;
Loading
Loading