Skip to content

Commit

Permalink
fix: build improvements, code cleanup, small improvements, test fixes
Browse files Browse the repository at this point in the history
* fix: add code splitting
* fix: differentiate dev/prod/test/etc modes from development/production builds
* chore: run e2e tests with production build
* fix: ensure all compile builds are done as production builds (only dev server runs with development builds)
* chore: add test id helper
* chore: replace all relative paths with tsconfig paths
* chore: improve button, dialog, textfield
* chore: cleanup dependencies
* chore: delete unused Settings page
* fix: fix demo translation
* fix: make payment tests more robust
* fix: fix IP override for tests
  • Loading branch information
dbudzins authored Nov 28, 2022
1 parent 3194970 commit 8891cee
Show file tree
Hide file tree
Showing 60 changed files with 288 additions and 286 deletions.
1 change: 1 addition & 0 deletions .commitlintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ module.exports = {
'inlineplayer',
'config',
'epg',
'tests',
],
],
},
Expand Down
File renamed without changes.
5 changes: 1 addition & 4 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,8 @@ This PR solves # .

According to our definition of done, I have completed the following steps:

- [ ] User stories met
- [ ] Storybook stories
- [ ] Acceptance criteria met
- [ ] Unit tests added
- [ ] Linting passing
- [ ] Unit tests passing
- [ ] Docs updated (including config and env variables)
- [ ] Translations added
- [ ] UX tested
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/codeceptjs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ jobs:
run: |
yarn
npm install wait-on -g
- name: Start dev server
run: yarn start --mode test &
- name: Start preview server
run: yarn start:test &
- name: Run tests
run: wait-on -v -t 30000 -c ./scripts/waitOnConfig.js http-get://localhost:8080 && yarn codecept:${{ matrix.config }}
env:
Expand Down
9 changes: 4 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
"version": "2.7.0",
"main": "index.js",
"repository": "https://github.com/jwplayer/ott-web-app.git",
"author": "Robin van Zanten",
"author": "JW Player",
"private": true,
"engines": {
"node": ">=16.0.0"
},
"scripts": {
"prepare": "husky install",
"start": "vite",
"start:test": "vite build --mode test && vite preview --port 8080",
"build": "vite build",
"test": "TZ=UTC vitest run",
"test-watch": "TZ=UTC vitest",
Expand Down Expand Up @@ -38,17 +39,14 @@
"deploy:github": "node ./scripts/deploy-github.js"
},
"dependencies": {
"allure-commandline": "^2.17.2",
"classnames": "^2.3.1",
"date-fns": "^2.28.0",
"dompurify": "^2.3.8",
"history": "^4.10.1",
"i18next": "^20.3.1",
"i18next-browser-languagedetector": "^6.1.1",
"jwt-decode": "^3.1.2",
"lodash.merge": "^4.6.2",
"marked": "^4.1.1",
"npm-run-all": "^4.1.5",
"planby": "^0.3.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
Expand Down Expand Up @@ -78,11 +76,11 @@
"@types/react-dom": "^17.0.9",
"@types/react-helmet": "^6.1.2",
"@types/react-infinite-scroller": "^1.2.3",
"@types/react-router-dom": "^5.3.3",
"@typescript-eslint/eslint-plugin": "^5.17.0",
"@typescript-eslint/parser": "^5.17.0",
"@vitejs/plugin-react": "^1.0.7",
"@vitest/coverage-c8": "^0.23.4",
"allure-commandline": "^2.17.2",
"codeceptjs": "3.3.0",
"confusing-browser-globals": "^1.0.10",
"depcheck": "^1.4.3",
Expand All @@ -97,6 +95,7 @@
"jsdom": "^19.0.0",
"lint-staged": "^10.5.4",
"luxon": "^3.1.0",
"npm-run-all": "^4.1.5",
"playwright": "^1.25.2",
"postcss": "^8.3.5",
"postcss-import": "^14.0.2",
Expand Down
12 changes: 12 additions & 0 deletions src/components/Button/Button.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,15 @@ $large-button-height: 40px;
}
}
}

.hidden {
visibility: hidden;
}

.centerAbsolute {
position: absolute;
right: 0;
left: 0;
margin: auto;
transform: translate(-5px, -5px);
}
34 changes: 22 additions & 12 deletions src/components/Button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { NavLink } from 'react-router-dom';

import styles from './Button.module.scss';

import Spinner from '#src/components/Spinner/Spinner';

type Color = 'default' | 'primary';

type Variant = 'contained' | 'outlined' | 'text';
Expand All @@ -24,6 +26,7 @@ type Props = {
className?: string;
type?: 'button' | 'submit' | 'reset';
disabled?: boolean;
busy?: boolean;
id?: string;
} & React.AriaAttributes;

Expand All @@ -37,6 +40,7 @@ const Button: React.FC<Props> = ({
variant = 'outlined',
size = 'medium',
disabled,
busy,
type,
to,
onClick,
Expand All @@ -52,20 +56,26 @@ const Button: React.FC<Props> = ({
[styles.disabled]: disabled,
});

const icon = startIcon ? <div className={styles.startIcon}>{startIcon}</div> : null;
const span = <span className={styles.buttonLabel}>{label}</span>;

return to ? (
<NavLink className={({ isActive }) => buttonClassName(isActive)} to={to} {...rest} end>
{icon}
{span}
const content = (
<>
{startIcon && <div className={styles.startIcon}>{startIcon}</div>}
{<span className={classNames(styles.buttonLabel, { [styles.hidden]: busy }) || undefined}>{label}</span>}
{children}
</NavLink>
) : (
{busy && <Spinner className={styles.centerAbsolute} size={'small'} />}
</>
);

if (to) {
return (
<NavLink className={({ isActive }) => buttonClassName(isActive)} to={to} {...rest} end>
{content}
</NavLink>
);
}

return (
<button className={buttonClassName(active)} onClick={onClick} type={type} disabled={disabled} aria-disabled={disabled} {...rest}>
{icon}
{span}
{children}
{content}
</button>
);
};
Expand Down
4 changes: 2 additions & 2 deletions src/components/ChooseOfferForm/ChooseOfferForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import CheckCircle from '#src/icons/CheckCircle';
import type { Offer } from '#types/checkout';
import { getOfferPrice, isSVODOffer } from '#src/utils/subscription';
import type { FormErrors } from '#types/form';
import { IS_DEV_BUILD } from '#src/utils/common';
import { testId } from '#src/utils/common';
import type { ChooseOfferFormData, OfferType } from '#types/account';
import { useConfigStore } from '#src/stores/ConfigStore';

Expand Down Expand Up @@ -139,7 +139,7 @@ const ChooseOfferForm: React.FC<Props> = ({
};

return (
<form onSubmit={onSubmit} data-testid={IS_DEV_BUILD ? 'choose-offer-form' : undefined} noValidate>
<form onSubmit={onSubmit} data-testid={testId('choose-offer-form')} noValidate>
{onBackButtonClickHandler ? <DialogBackButton onClick={onBackButtonClickHandler} /> : null}
<h2 className={styles.title}>{t('choose_offer.title')}</h2>
<h3 className={styles.subtitle}>{t('choose_offer.watch_this_on_platform', { siteName })}</h3>
Expand Down
16 changes: 13 additions & 3 deletions src/components/ConfirmationDialog/ConfirmationDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,27 @@ type Props = {
body: string;
onConfirm: () => void;
onClose: () => void;
busy?: boolean;
};

const ConfirmationDialog: React.FC<Props> = ({ open, title, body, onConfirm, onClose }: Props) => {
const ConfirmationDialog: React.FC<Props> = ({ open, title, body, onConfirm, onClose, busy }: Props) => {
const { t } = useTranslation('common');

return (
<Dialog open={open} onClose={onClose}>
<h2 className={styles.title}>{title}</h2>
<p className={styles.body}>{body}</p>
<Button className={styles.confirmButton} label={t('confirmation_dialog.confirm')} variant="contained" color="primary" onClick={onConfirm} fullWidth />
<Button label={t('confirmation_dialog.close')} variant="outlined" onClick={onClose} fullWidth />
<Button
className={styles.confirmButton}
label={t('confirmation_dialog.confirm')}
variant={'contained'}
color={busy ? 'default' : 'primary'}
onClick={onConfirm}
fullWidth
disabled={busy}
busy={busy}
/>
<Button label={t('confirmation_dialog.close')} variant="outlined" onClick={onClose} fullWidth disabled={busy} />
</Dialog>
);
};
Expand Down
2 changes: 1 addition & 1 deletion src/components/DemoConfigDialog/DemoConfigDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const DemoConfigDialog = ({ configLocation = getConfigLocation() }: Props) => {
if (configLocation) {
return (
<div className={styles.note}>
<div>{t('currently_previewing_config', { configLocation })}</div>
<div>{t('currently_previewing_config', { configSource: configLocation })}</div>
<Link onClick={clearConfig}>{t('click_to_unselect_config')}</Link>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ exports[`<DemoConfigDialog> > renders and matches snapshot 1`] = `
placeholder="please_enter_config_id"
required=""
type="text"
value=""
/>
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/components/EditPasswordForm/EditPasswordForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import Visibility from '#src/icons/Visibility';
import VisibilityOff from '#src/icons/VisibilityOff';
import PasswordStrength from '#components/PasswordStrength/PasswordStrength';
import LoadingOverlay from '#components/LoadingOverlay/LoadingOverlay';
import { IS_DEV_BUILD } from '#src/utils/common';
import { testId } from '#src/utils/common';
import useToggle from '#src/hooks/useToggle';
import type { EditPasswordFormData } from '#types/account';
import type { FormErrors } from '#types/form';
Expand All @@ -31,7 +31,7 @@ const EditPasswordForm: React.FC<Props> = ({ onSubmit, onChange, onBlur, value,
const [viewPassword, toggleViewPassword] = useToggle();

return (
<form onSubmit={onSubmit} data-testid={IS_DEV_BUILD ? 'forgot-password-form' : undefined} noValidate className={styles.forgotPasswordForm}>
<form onSubmit={onSubmit} data-testid={testId('forgot-password-form')} noValidate className={styles.forgotPasswordForm}>
<h2 className={styles.title}>{t('reset.password_reset')}</h2>
{errors.form ? <FormFeedback variant="error">{errors.form}</FormFeedback> : null}
<TextField
Expand Down
3 changes: 2 additions & 1 deletion src/components/EpgChannel/EpgChannelItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import classNames from 'classnames';
import styles from './EpgChannelItem.module.scss';

import Image from '#components/Image/Image';
import { testId } from '#src/utils/common';

type Props = {
channel: Channel;
Expand All @@ -24,7 +25,7 @@ const EpgChannelItem: React.VFC<Props> = ({ channel, channelItemWidth, sidebarWi
className={classNames(styles.epgChannel, { [styles.active]: isActive })}
style={{ width: channelItemWidth }}
onClick={() => onClick && onClick(channel)}
data-testid={uuid}
data-testid={testId(uuid)}
>
<Image className={styles.epgChannelLogo} image={channelLogoImage} alt="Logo" width={320} />
</div>
Expand Down
4 changes: 3 additions & 1 deletion src/components/EpgProgramItem/EpgProgramItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { useTranslation } from 'react-i18next';

import styles from './EpgProgramItem.module.scss';

import { testId } from '#src/utils/common';

type Props = {
program: Program;
onClick?: (program: Program) => void;
Expand Down Expand Up @@ -45,7 +47,7 @@ const ProgramItem: React.VFC<Props> = ({ program, onClick, isActive, compact, di
[styles.disabled]: disabled,
})}
style={{ width: styles.width }}
data-testid={program.data.id}
data-testid={testId(program.data.id)}
>
{showImage && <img className={styles.epgProgramImage} src={image} alt="Preview" />}
{showLiveTagInImage && <div className={styles.epgLiveTag}>{t('live')}</div>}
Expand Down
4 changes: 2 additions & 2 deletions src/components/ForgotPasswordForm/ForgotPasswordForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import styles from './ForgotPasswordForm.module.scss';
import Button from '#components/Button/Button';
import TextField from '#components/TextField/TextField';
import FormFeedback from '#components/FormFeedback/FormFeedback';
import { IS_DEV_BUILD } from '#src/utils/common';
import { testId } from '#src/utils/common';
import type { ForgotPasswordFormData } from '#types/account';
import type { FormErrors } from '#types/form';

Expand All @@ -24,7 +24,7 @@ const ForgotPasswordForm: React.FC<Props> = ({ onSubmit, onChange, value, errors
const { t } = useTranslation('account');

return (
<form onSubmit={onSubmit} data-testid={IS_DEV_BUILD ? 'forgot-password-form' : undefined} noValidate className={styles.forgotPasswordForm}>
<form onSubmit={onSubmit} data-testid={testId('forgot-password-form')} noValidate className={styles.forgotPasswordForm}>
<h2 className={styles.title}>{t('reset.forgot_password')}</h2>
{errors.form ? <FormFeedback variant="error">{errors.form}</FormFeedback> : null}
<p className={styles.text}>{t('reset.forgot_text')}</p>
Expand Down
4 changes: 2 additions & 2 deletions src/components/LoginForm/LoginForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import Visibility from '#src/icons/Visibility';
import VisibilityOff from '#src/icons/VisibilityOff';
import FormFeedback from '#components/FormFeedback/FormFeedback';
import LoadingOverlay from '#components/LoadingOverlay/LoadingOverlay';
import { IS_DEV_BUILD } from '#src/utils/common';
import { testId } from '#src/utils/common';
import useToggle from '#src/hooks/useToggle';
import { addQueryParam } from '#src/utils/location';
import type { FormErrors } from '#types/form';
Expand All @@ -34,7 +34,7 @@ const LoginForm: React.FC<Props> = ({ onSubmit, onChange, values, errors, submit
const location = useLocation();

return (
<form onSubmit={onSubmit} data-testid={IS_DEV_BUILD ? 'login-form' : undefined} noValidate>
<form onSubmit={onSubmit} data-testid={testId('login-form')} noValidate>
<h2 className={styles.title}>{t('login.sign_in')}</h2>
{errors.form ? <FormFeedback variant="error">{errors.form}</FormFeedback> : null}
<TextField
Expand Down
4 changes: 2 additions & 2 deletions src/components/Modal/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import styles from './Modal.module.scss';
import scrollbarSize from '#src/utils/dom';
import Fade from '#components/Animation/Fade/Fade';
import Grow from '#components/Animation/Grow/Grow';
import { IS_DEV_BUILD } from '#src/utils/common';
import { testId } from '#src/utils/common';

type Props = {
children?: React.ReactNode;
Expand Down Expand Up @@ -77,7 +77,7 @@ const Modal: React.FC<Props> = ({ open, onClose, children, AnimationComponent =
return ReactDOM.createPortal(
<Fade open={open} duration={300} onCloseAnimationEnd={() => setVisible(false)}>
<div className={styles.modal} onKeyDown={keyDownEventHandler} ref={modalRef}>
<div className={styles.backdrop} onClick={onClose} data-testid={IS_DEV_BUILD ? 'backdrop' : undefined} />
<div className={styles.backdrop} onClick={onClose} data-testid={testId('backdrop')} />
<div className={styles.container}>
<AnimationComponent open={open} duration={200}>
{children}
Expand Down
4 changes: 2 additions & 2 deletions src/components/PersonalDetailsForm/PersonalDetailsForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import Radio from '#components/Radio/Radio';
import DateField from '#components/DateField/DateField';
import LoadingOverlay from '#components/LoadingOverlay/LoadingOverlay';
import FormFeedback from '#components/FormFeedback/FormFeedback';
import { IS_DEV_BUILD } from '#src/utils/common';
import { testId } from '#src/utils/common';
import type { FormErrors } from '#types/form';
import type { PersonalDetailsFormData, CleengCaptureField, CleengCaptureQuestionField } from '#types/account';

Expand Down Expand Up @@ -67,7 +67,7 @@ const PersonalDetailsForm: React.FC<Props> = ({
};

return (
<form onSubmit={onSubmit} data-testid={IS_DEV_BUILD ? 'personal_details-form' : undefined} noValidate>
<form onSubmit={onSubmit} data-testid={testId('personal_details-form')} noValidate>
<h2 className={styles.title}>{t('personal_details.title')}</h2>
{errors.form ? <FormFeedback variant="error">{errors.form}</FormFeedback> : null}
{fields.firstNameLastName?.enabled ? (
Expand Down
4 changes: 2 additions & 2 deletions src/components/Player/Player.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type { JWPlayer } from '#types/jwplayer';
import type { PlaylistItem } from '#types/playlist';
import useEventCallback from '#src/hooks/useEventCallback';
import useOttAnalytics from '#src/hooks/useOttAnalytics';
import { logDev } from '#src/utils/common';
import { logDev, testId } from '#src/utils/common';

type Props = {
playerId: string;
Expand Down Expand Up @@ -193,7 +193,7 @@ const Player: React.FC<Props> = ({
}, [detachEvents]);

return (
<div className={styles.container} data-testid="player-container">
<div className={styles.container} data-testid={testId('player-container')}>
<div ref={playerElementRef} />
</div>
);
Expand Down
4 changes: 2 additions & 2 deletions src/components/RegistrationForm/RegistrationForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import Checkbox from '#components/Checkbox/Checkbox';
import FormFeedback from '#components/FormFeedback/FormFeedback';
import LoadingOverlay from '#components/LoadingOverlay/LoadingOverlay';
import Link from '#components/Link/Link';
import { IS_DEV_BUILD } from '#src/utils/common';
import { testId } from '#src/utils/common';
import useToggle from '#src/hooks/useToggle';
import { addQueryParam } from '#src/utils/location';
import type { FormErrors } from '#types/form';
Expand Down Expand Up @@ -76,7 +76,7 @@ const RegistrationForm: React.FC<Props> = ({
}

return (
<form onSubmit={onSubmit} data-testid={IS_DEV_BUILD ? 'registration-form' : undefined} noValidate>
<form onSubmit={onSubmit} data-testid={testId('registration-form')} noValidate>
<h2 className={styles.title}>{t('registration.sign_up')}</h2>
{errors.form ? <FormFeedback variant="error">{errors.form}</FormFeedback> : null}
<TextField
Expand Down
Loading

0 comments on commit 8891cee

Please sign in to comment.