diff --git a/apps/client/src/common/components/client-modal/RenameClientModal.tsx b/apps/client/src/common/components/client-modal/RenameClientModal.tsx index 4dbf95ea4..dc6e03625 100644 --- a/apps/client/src/common/components/client-modal/RenameClientModal.tsx +++ b/apps/client/src/common/components/client-modal/RenameClientModal.tsx @@ -1,17 +1,9 @@ import { useState } from 'react'; -import { - Button, - Input, - Modal, - ModalBody, - ModalCloseButton, - ModalContent, - ModalFooter, - ModalHeader, - ModalOverlay, -} from '@chakra-ui/react'; +import Button from '../../../common/components/buttons/Button'; import { setClientRemote } from '../../hooks/useSocket'; +import Dialog from '../dialog/Dialog'; +import Input from '../input/input/Input'; interface RenameClientModalProps { id: string; @@ -20,8 +12,7 @@ interface RenameClientModalProps { onClose: () => void; } -export function RenameClientModal(props: RenameClientModalProps) { - const { id, name: currentName = '', isOpen, onClose } = props; +export function RenameClientModal({ id, name: currentName = '', isOpen, onClose }: RenameClientModalProps) { const [name, setName] = useState(currentName); const { setClientName } = setClientRemote; @@ -36,29 +27,24 @@ export function RenameClientModal(props: RenameClientModalProps) { const canSubmit = name !== currentName && name !== ''; return ( - - - - Rename: {currentName} - - - setName(event.target.value)} - /> - - - - - - - + + } + /> ); } diff --git a/apps/client/src/common/components/navigation-menu/NavigationMenu.module.scss b/apps/client/src/common/components/navigation-menu/NavigationMenu.module.scss index a2f9808aa..613d8c298 100644 --- a/apps/client/src/common/components/navigation-menu/NavigationMenu.module.scss +++ b/apps/client/src/common/components/navigation-menu/NavigationMenu.module.scss @@ -1,107 +1,68 @@ -@use '../../../theme/mixins' as *; - -$menu-hover-bg: $gray-1350; -$menu-focus-bg: $gray-1300; - -$button-size: 3rem; - -.fadeable { - opacity: 1; - - transition-property: opacity; - transition-duration: 0.3s; - - &.hidden { - opacity: 0; - pointer-events: none; - } -} - -.lockIcon { - font-size: 1.5rem; - color: $active-indicator; - padding: 0.5em; - - position: fixed; - left: 0; - top: 0; - z-index: 12; -} - -.buttonContainer { - display: flex; - flex-direction: column; - row-gap: 1rem; - padding: 0.5em; - - position: fixed; - left: 0; - top: 0; - z-index: 12; -} - -.navButton { - font-size: 1.5rem; - height: $button-size; - width: $button-size;; -} - -.link { - @include action-link; - padding: 0.75rem 1.5rem; - gap: 0.5rem; - width: 100%; - cursor: pointer; - - &:hover { - background-color: $menu-hover-bg; - } - - &:active { - background-color: $border-color-ondark; - } - - &:focus { - outline: none; - background-color: $menu-focus-bg; - border-left: 2px solid $action-text-color; - } - - &.current { - background-color: $menu-hover-bg; - border-left: 4px solid $action-text-color; - } -} - -.linkIcon { - margin-left: auto; - @include rotate-fourty-five; -} - .separator { border-color: $border-color-ondark; } -.sectionHeader { - font-size: calc(1rem - 2px); - margin-left: 1rem; - color: $gray-700; +.backdrop { + position: fixed; + inset: 0; + z-index: $zindex-backdrop; + background-color: $backdrop-color; + transition: opacity 300ms cubic-bezier(0.45, 1.005, 0, 1.005); + + &[data-starting-style], + &[data-ending-style] { + opacity: 0; + } } -.bottom { - margin-top: auto; - margin-bottom: 1rem; -} +.drawer { + box-sizing: border-box; + position: fixed; + top: 0; + left: 0; + bottom: 0; + z-index: $zindex-dialog; + + width: 22rem; + height: 100vh; -.interfaces { - padding: 0.5rem 1rem; display: flex; - flex-wrap: wrap; - gap: 0.5rem; + flex-direction: column; + padding-block: 1rem; + + background-color: $gray-1250; + color: $ui-white; + border-right: 1px solid $gray-1200; + + &[data-open] { + transform: translateX(0%); + transition: transform 300ms cubic-bezier(0.45, 1.005, 0, 1.005); + } + + &[data-starting-style], + &[data-ending-style] { + transform: translateX(-100%); + transition: transform 500ms cubic-bezier(0.45, 1.005, 0, 1.005); + } + + // take the whole screen in mobile devices + @media (max-width: $min-tablet) { + width: 100vw; + } } -.goIcon { - @include rotate-fourty-five; - margin-left: 0.25rem; - margin-bottom: 0.25rem; +.header { + display: flex; + align-items: center; + justify-content: space-between; + height: 3.5rem; + padding-inline: 1.5rem; + + font-weight: 600; + font-size: 1.25rem; +} + +.body { + flex: 1; + overflow-y: auto; } diff --git a/apps/client/src/common/components/navigation-menu/NavigationMenu.tsx b/apps/client/src/common/components/navigation-menu/NavigationMenu.tsx index 914cd7b74..233ccb618 100644 --- a/apps/client/src/common/components/navigation-menu/NavigationMenu.tsx +++ b/apps/client/src/common/components/navigation-menu/NavigationMenu.tsx @@ -1,29 +1,20 @@ -import { memo, PropsWithChildren } from 'react'; -import { createPortal } from 'react-dom'; -import { IoArrowUp, IoContract, IoExpand, IoLockClosedOutline, IoSwapVertical } from 'react-icons/io5'; -import { Link, useLocation } from 'react-router-dom'; -import { - Drawer, - DrawerBody, - DrawerCloseButton, - DrawerContent, - DrawerHeader, - DrawerOverlay, - useDisclosure, -} from '@chakra-ui/react'; -import { useFullscreen } from '@mantine/hooks'; +import { memo } from 'react'; +import { IoClose, IoContract, IoExpand, IoLockClosedOutline, IoSwapVertical } from 'react-icons/io5'; +import { useLocation } from 'react-router-dom'; +import { Dialog } from '@base-ui-components/react/dialog'; +import { useDisclosure, useFullscreen } from '@mantine/hooks'; import { isLocalhost } from '../../../externals'; import { navigatorConstants } from '../../../viewerConfig'; -import { useElectronEvent } from '../../hooks/useElectronEvent'; -import useInfo from '../../hooks-query/useInfo'; import { useClientStore } from '../../stores/clientStore'; import { useViewOptionsStore } from '../../stores/viewOptions'; -import { isKeyEnter } from '../../utils/keyEvent'; -import { handleLinks, linkToOtherHost, openLink } from '../../utils/linkUtils'; -import { cx } from '../../utils/styleUtils'; +import IconButton from '../buttons/IconButton'; import { RenameClientModal } from '../client-modal/RenameClientModal'; -import CopyTag from '../copy-tag/CopyTag'; + +import ClientLink from './client-link/ClientLink'; +import EditorNavigation from './editor-navigation/EditorNavigation'; +import NavigationMenuItem from './navigation-menu-item/NavigationMenuItem'; +import OtherAddresses from './other-addresses/OtherAddresses'; import style from './NavigationMenu.module.scss'; @@ -32,74 +23,49 @@ interface NavigationMenuProps { onClose: () => void; } -function NavigationMenu(props: NavigationMenuProps) { - const { isOpen, onClose } = props; - +export default memo(NavigationMenu); +function NavigationMenu({ isOpen, onClose }: NavigationMenuProps) { const id = useClientStore((store) => store.id); const name = useClientStore((store) => store.name); - const { isOpen: isOpenRename, onOpen: onRenameOpen, onClose: onCloseRename } = useDisclosure(); + const [isRenameOpen, handlers] = useDisclosure(false); const { fullscreen, toggle } = useFullscreen(); const { mirror, toggleMirror } = useViewOptionsStore(); const location = useLocation(); - return createPortal( - + + {isLocalhost && ( +
+ +
+ )} + + + ); } - -interface OtherAddressesProps { - currentLocation: string; -} - -function OtherAddresses(props: OtherAddressesProps) { - const { currentLocation } = props; - const { data } = useInfo(); - - // there is no point showing this if we only have one interface - if (data.networkInterfaces.length < 2) { - return null; - } - - return ( -
-
Accessible on external networks
-
- {data?.networkInterfaces?.map((nif) => { - if (nif.name === 'localhost') { - return null; - } - - const address = linkToOtherHost(nif.address, currentLocation); - - return ( - openLink(address)} - label='Copy IP or navigate to address' - > - {nif.address} - - ); - })} -
-
- ); -} - -interface ClientLinkProps { - current: boolean; - to: string; -} - -function ClientLink(props: PropsWithChildren) { - const { current, to, children } = props; - const { isElectron } = useElectronEvent(); - - const classes = cx([style.link, current && style.current]); - - if (isElectron) { - return ( - - ); - } - - return ( - - {children} - - ); -} - -export default memo(NavigationMenu); diff --git a/apps/client/src/common/components/navigation-menu/ViewNavigationMenu.tsx b/apps/client/src/common/components/navigation-menu/ViewNavigationMenu.tsx index 4490c5a81..652fe03d2 100644 --- a/apps/client/src/common/components/navigation-menu/ViewNavigationMenu.tsx +++ b/apps/client/src/common/components/navigation-menu/ViewNavigationMenu.tsx @@ -2,10 +2,10 @@ import { memo } from 'react'; import { useDisclosure } from '@chakra-ui/react'; import { useHotkeys } from '@mantine/hooks'; -import FloatingNavigation from './FloatingNavigation'; +import FloatingNavigation from './floating-navigation/FloatingNavigation'; +import ViewLockedIcon from './view-locked-icon/ViewLockedIcon'; import NavigationMenu from './NavigationMenu'; import useViewEditor from './useViewEditor'; -import ViewLockedIcon from './ViewLockedIcon'; interface ViewNavigationMenuProps { isLockable?: boolean; diff --git a/apps/client/src/common/components/navigation-menu/client-link/ClientLink.module.scss b/apps/client/src/common/components/navigation-menu/client-link/ClientLink.module.scss new file mode 100644 index 000000000..431a04308 --- /dev/null +++ b/apps/client/src/common/components/navigation-menu/client-link/ClientLink.module.scss @@ -0,0 +1,4 @@ +.linkIcon { + margin-left: auto; + @include rotate-fourty-five; +} diff --git a/apps/client/src/common/components/navigation-menu/client-link/ClientLink.tsx b/apps/client/src/common/components/navigation-menu/client-link/ClientLink.tsx new file mode 100644 index 000000000..1d7e507d1 --- /dev/null +++ b/apps/client/src/common/components/navigation-menu/client-link/ClientLink.tsx @@ -0,0 +1,34 @@ +import { PropsWithChildren } from 'react'; +import { IoArrowUp } from 'react-icons/io5'; +import { useNavigate } from 'react-router-dom'; + +import { useElectronEvent } from '../../../hooks/useElectronEvent'; +import { handleLinks } from '../../../utils/linkUtils'; +import NavigationMenuItem from '../navigation-menu-item/NavigationMenuItem'; + +import style from './ClientLink.module.scss'; + +interface ClientLinkProps { + current: boolean; + to: string; +} + +export default function ClientLink({ current, to, children }: PropsWithChildren) { + const { isElectron } = useElectronEvent(); + const navigate = useNavigate(); + + if (isElectron) { + return ( + handleLinks(to)}> + {children} + + + ); + } + + return ( + navigate(`/${to}`)}> + {children} + + ); +} diff --git a/apps/client/src/common/components/navigation-menu/editor-navigation/EditorNavigation.tsx b/apps/client/src/common/components/navigation-menu/editor-navigation/EditorNavigation.tsx new file mode 100644 index 000000000..0d94221c5 --- /dev/null +++ b/apps/client/src/common/components/navigation-menu/editor-navigation/EditorNavigation.tsx @@ -0,0 +1,38 @@ +import { IoLockClosedOutline } from 'react-icons/io5'; +import { useNavigate } from 'react-router-dom'; +import { useViewportSize } from '@mantine/hooks'; + +import NavigationMenuItem from '../navigation-menu-item/NavigationMenuItem'; + +export default function EditorNavigation() { + const { width } = useViewportSize(); + const navigate = useNavigate(); + + if (width > 1440) { + return ( + navigate('/editor')}> + + Editor + + ); + } + + return ( + <> + navigate('/timercontrol')}> + + Timer Controls + + + navigate('/messagecontrol')}> + + Message Controls + + + navigate('/rundown')}> + + Rundown + + + ); +} diff --git a/apps/client/src/common/components/navigation-menu/floating-navigation/FloatingNavigation.module.scss b/apps/client/src/common/components/navigation-menu/floating-navigation/FloatingNavigation.module.scss new file mode 100644 index 000000000..ea5279118 --- /dev/null +++ b/apps/client/src/common/components/navigation-menu/floating-navigation/FloatingNavigation.module.scss @@ -0,0 +1,23 @@ +.fadeable { + opacity: 1; + + transition-property: opacity; + transition-duration: 0.3s; + + &.hidden { + opacity: 0; + pointer-events: none; + } +} + +.buttonContainer { + display: flex; + flex-direction: column; + row-gap: 1rem; + padding: 0.5em; + + position: fixed; + left: 0; + top: 0; + z-index: $zindex-nav; +} diff --git a/apps/client/src/common/components/navigation-menu/FloatingNavigation.tsx b/apps/client/src/common/components/navigation-menu/floating-navigation/FloatingNavigation.tsx similarity index 53% rename from apps/client/src/common/components/navigation-menu/FloatingNavigation.tsx rename to apps/client/src/common/components/navigation-menu/floating-navigation/FloatingNavigation.tsx index a38454344..0301bdd16 100644 --- a/apps/client/src/common/components/navigation-menu/FloatingNavigation.tsx +++ b/apps/client/src/common/components/navigation-menu/floating-navigation/FloatingNavigation.tsx @@ -1,26 +1,28 @@ import { IoApps } from 'react-icons/io5'; import { IoSettingsOutline } from 'react-icons/io5'; -import { useFadeOutOnInactivity } from '../../hooks/useFadeOutOnInactivity'; -import { cx } from '../../utils/styleUtils'; -import IconButton from '../buttons/IconButton'; +import { useFadeOutOnInactivity } from '../../../hooks/useFadeOutOnInactivity'; +import { cx } from '../../../utils/styleUtils'; +import IconButton from '../../buttons/IconButton'; -import style from './NavigationMenu.module.scss'; +import style from './FloatingNavigation.module.scss'; interface FloatingNavigationProps { toggleMenu: () => void; toggleSettings: () => void; } -export default function FloatingNavigation(props: FloatingNavigationProps) { - const { toggleMenu, toggleSettings } = props; - const isButtonShown = useFadeOutOnInactivity(); +export default function FloatingNavigation({ toggleMenu, toggleSettings }: FloatingNavigationProps) { + const isButtonShown = useFadeOutOnInactivity(true); return ( -
+
void; +} + +export default function NavigationMenuItem({ + active, + className, + children, + onClick, +}: PropsWithChildren) { + return ( +
{ + isKeyEnter(event) && onClick(); + }} + > + {children} +
+ ); +} diff --git a/apps/client/src/common/components/navigation-menu/other-addresses/OtherAddresses.module.scss b/apps/client/src/common/components/navigation-menu/other-addresses/OtherAddresses.module.scss new file mode 100644 index 000000000..50ca4ee8c --- /dev/null +++ b/apps/client/src/common/components/navigation-menu/other-addresses/OtherAddresses.module.scss @@ -0,0 +1,18 @@ +.header { + font-size: calc(1rem - 2px); + margin-left: 1rem; + color: $gray-700; +} + +.interfaces { + padding: 0.5rem 1rem; + display: flex; + flex-wrap: wrap; + gap: 0.5rem; +} + +.goIcon { + @include rotate-fourty-five; + margin-left: 0.25rem; + margin-bottom: 0.25rem; +} diff --git a/apps/client/src/common/components/navigation-menu/other-addresses/OtherAddresses.tsx b/apps/client/src/common/components/navigation-menu/other-addresses/OtherAddresses.tsx new file mode 100644 index 000000000..d4a47191f --- /dev/null +++ b/apps/client/src/common/components/navigation-menu/other-addresses/OtherAddresses.tsx @@ -0,0 +1,46 @@ +import { IoArrowUp } from 'react-icons/io5'; + +import useInfo from '../../../hooks-query/useInfo'; +import { linkToOtherHost, openLink } from '../../../utils/linkUtils'; +import CopyTag from '../../copy-tag/CopyTag'; + +import style from './OtherAddresses.module.scss'; + +interface OtherAddressesProps { + currentLocation: string; +} + +export default function OtherAddresses({ currentLocation }: OtherAddressesProps) { + const { data } = useInfo(); + + // there is no point showing this if we only have one interface + if (data.networkInterfaces.length < 2) { + return null; + } + + return ( + <> +
Accessible on external networks
+
+ {data?.networkInterfaces?.map((nif) => { + if (nif.name === 'localhost') { + return null; + } + + const address = linkToOtherHost(nif.address, currentLocation); + + return ( + openLink(address)} + label='Copy IP or navigate to address' + > + {nif.address} + + ); + })} +
+ + ); +} diff --git a/apps/client/src/common/components/navigation-menu/view-locked-icon/ViewLockedIcon.module.scss b/apps/client/src/common/components/navigation-menu/view-locked-icon/ViewLockedIcon.module.scss new file mode 100644 index 000000000..5995cbb4d --- /dev/null +++ b/apps/client/src/common/components/navigation-menu/view-locked-icon/ViewLockedIcon.module.scss @@ -0,0 +1,22 @@ +.fadeable { + opacity: 1; + + transition-property: opacity; + transition-duration: 0.3s; + + &.hidden { + opacity: 0; + pointer-events: none; + } +} + +.lockIcon { + font-size: 1.5rem; + color: $active-indicator; + padding: 0.5em; + + position: fixed; + left: 0; + top: 0; + z-index: $zindex-nav; +} diff --git a/apps/client/src/common/components/navigation-menu/ViewLockedIcon.tsx b/apps/client/src/common/components/navigation-menu/view-locked-icon/ViewLockedIcon.tsx similarity index 63% rename from apps/client/src/common/components/navigation-menu/ViewLockedIcon.tsx rename to apps/client/src/common/components/navigation-menu/view-locked-icon/ViewLockedIcon.tsx index 3afe50cad..3dfac5561 100644 --- a/apps/client/src/common/components/navigation-menu/ViewLockedIcon.tsx +++ b/apps/client/src/common/components/navigation-menu/view-locked-icon/ViewLockedIcon.tsx @@ -1,9 +1,9 @@ import { IoLockClosedOutline } from 'react-icons/io5'; -import { useFadeOutOnInactivity } from '../../hooks/useFadeOutOnInactivity'; -import { cx } from '../../utils/styleUtils'; +import { useFadeOutOnInactivity } from '../../../hooks/useFadeOutOnInactivity'; +import { cx } from '../../../utils/styleUtils'; -import style from './NavigationMenu.module.scss'; +import style from './ViewLockedIcon.module.scss'; export default function ViewLockedIcon() { const isLockIconShown = useFadeOutOnInactivity(); diff --git a/apps/client/src/common/utils/linkUtils.ts b/apps/client/src/common/utils/linkUtils.ts index 98f0aec32..db2b0707c 100644 --- a/apps/client/src/common/utils/linkUtils.ts +++ b/apps/client/src/common/utils/linkUtils.ts @@ -20,13 +20,13 @@ export function openLink(url: string) { * serverUrl and baseURI are used for testing */ export function handleLinks( - event: MouseEvent, location: string, + event?: MouseEvent, externalServerUrl: string = serverURL, externalBaseURI: string = baseURI, ) { // we handle the link manually - event.preventDefault(); + event?.preventDefault(); const destination = new URL(externalServerUrl); destination.pathname = externalBaseURI ? `${externalBaseURI}/${location}` : location; diff --git a/apps/client/src/features/app-settings/panel/feature-settings-panel/UrlPresetsForm.tsx b/apps/client/src/features/app-settings/panel/feature-settings-panel/UrlPresetsForm.tsx index 4e1209a3c..db7553550 100644 --- a/apps/client/src/features/app-settings/panel/feature-settings-panel/UrlPresetsForm.tsx +++ b/apps/client/src/features/app-settings/panel/feature-settings-panel/UrlPresetsForm.tsx @@ -198,7 +198,7 @@ export default function UrlPresetsForm() { handleLinks(event, preset.alias)} + clickHandler={(event) => handleLinks(preset.alias, event)} tooltip='Test preset' aria-label='Test preset' variant='ontime-ghosted' diff --git a/apps/client/src/features/app-settings/panel/network-panel/NetworkLogExport.tsx b/apps/client/src/features/app-settings/panel/network-panel/NetworkLogExport.tsx index c0979bebd..45724679c 100644 --- a/apps/client/src/features/app-settings/panel/network-panel/NetworkLogExport.tsx +++ b/apps/client/src/features/app-settings/panel/network-panel/NetworkLogExport.tsx @@ -10,7 +10,7 @@ import style from './NetworkLogExport.module.scss'; export default function LogExport() { const extract = (event: MouseEvent) => { - handleLinks(event, 'log'); + handleLinks('log', event); }; return ( diff --git a/apps/client/src/features/control/message/MessageControlExport.jsx b/apps/client/src/features/control/message/MessageControlExport.jsx index 0dd7b036a..9f5fbf117 100644 --- a/apps/client/src/features/control/message/MessageControlExport.jsx +++ b/apps/client/src/features/control/message/MessageControlExport.jsx @@ -15,7 +15,7 @@ const MessageControlExport = () => { return (
- {!isExtracted && handleLinks(event, 'messagecontrol')} />} + {!isExtracted && handleLinks('messagecontrol', event)} />}
diff --git a/apps/client/src/features/control/message/TimerPreview.tsx b/apps/client/src/features/control/message/TimerPreview.tsx index 3a3db72f5..1ba9636b3 100644 --- a/apps/client/src/features/control/message/TimerPreview.tsx +++ b/apps/client/src/features/control/message/TimerPreview.tsx @@ -49,7 +49,7 @@ export default function TimerPreview() { return (
- handleLinks(event, 'timer')} /> + handleLinks('timer', event)} />
{ const isExtracted = window.location.pathname.includes('/timercontrol'); return (
- {!isExtracted && handleLinks(event, 'timercontrol')} />} + {!isExtracted && handleLinks('timercontrol', event)} />}
diff --git a/apps/client/src/features/rundown/RundownExport.tsx b/apps/client/src/features/rundown/RundownExport.tsx index 3298fcab9..145f0ca43 100644 --- a/apps/client/src/features/rundown/RundownExport.tsx +++ b/apps/client/src/features/rundown/RundownExport.tsx @@ -28,7 +28,7 @@ function RundownExport() {
- {!isExtracted && handleLinks(event, 'rundown')} />} + {!isExtracted && handleLinks('rundown', event)} />} diff --git a/apps/client/src/theme/_mixins.scss b/apps/client/src/theme/_mixins.scss index 94d8fea27..4998a6bbd 100644 --- a/apps/client/src/theme/_mixins.scss +++ b/apps/client/src/theme/_mixins.scss @@ -2,20 +2,6 @@ //////////////////////////////////// general app elements -@mixin action-link { - color: $action-text-color; - display: flex; - align-items: center; - cursor: pointer; - transition-property: color; - transition-duration: $transition-time-action; - white-space: nowrap; - - &:hover { - color: $ontime-color; - } -} - @mixin ellipsis-text { white-space: nowrap; overflow: hidden; diff --git a/apps/client/src/viewerConfig.ts b/apps/client/src/viewerConfig.ts index 475e7c552..f45600ecc 100644 --- a/apps/client/src/viewerConfig.ts +++ b/apps/client/src/viewerConfig.ts @@ -1,7 +1,5 @@ export const navigatorConstants = [ { url: 'timer', label: 'Timer' }, - { url: 'minimal', label: 'Minimal Timer' }, - { url: 'clock', label: 'Wall Clock' }, { url: 'backstage', label: 'Backstage' }, { url: 'timeline', label: 'Timeline (beta)' }, { url: 'lower', label: 'Lower Thirds' }, diff --git a/e2e/tests/001-smoke-tests.spec.ts b/e2e/tests/001-smoke-tests.spec.ts index 2dff5e4a1..2c3a4f027 100644 --- a/e2e/tests/001-smoke-tests.spec.ts +++ b/e2e/tests/001-smoke-tests.spec.ts @@ -33,18 +33,6 @@ test.describe('pages routes are available', () => { await expect(page).toHaveTitle(/ontime/); }); - test('clock', async ({ page }) => { - await page.goto('http://localhost:4001/timer'); - - await expect(page).toHaveTitle(/ontime/); - }); - - test('minimal', async ({ page }) => { - await page.goto('http://localhost:4001/minimal'); - - await expect(page).toHaveTitle(/ontime/); - }); - test('backstage', async ({ page }) => { await page.goto('http://localhost:4001/backstage'); diff --git a/e2e/tests/002-view-navigation.spec.ts b/e2e/tests/002-view-navigation.spec.ts index 20e918d84..ba269b2ec 100644 --- a/e2e/tests/002-view-navigation.spec.ts +++ b/e2e/tests/002-view-navigation.spec.ts @@ -6,37 +6,23 @@ test.describe('test view navigation feature', () => { await expect(page.locator('data-testid=timer-view')).toBeVisible(); }); - test('Minimal', async ({ page }) => { - await openNavigationMenu(page); - await page.getByRole('link', { name: 'Minimal Timer' }).click(); - await expect(page.locator('data-testid=minimal-timer')).toBeVisible(); - await expect(page).toHaveURL('http://localhost:4001/minimal'); - }); - - test('Wall Clock', async ({ page }) => { - await openNavigationMenu(page); - await page.getByRole('link', { name: 'Wall Clock', exact: true }).click(); - await expect(page.locator('data-testid=clock-view')).toBeVisible(); - await expect(page).toHaveURL('http://localhost:4001/clock'); - }); - test('Timeline', async ({ page }) => { await openNavigationMenu(page); - await page.getByRole('link', { name: 'Timeline' }).click(); + await page.getByRole('button', { name: 'Timeline' }).click(); page.locator('data-testid=timeline-view'); await expect(page).toHaveURL('http://localhost:4001/timeline'); }); test('Backstage', async ({ page }) => { await openNavigationMenu(page); - await page.getByRole('link', { name: 'Backstage' }).click(); + await page.getByRole('button', { name: 'Backstage' }).click(); page.locator('data-testid=backstage-view'); await expect(page).toHaveURL('http://localhost:4001/backstage'); }); test('Lower Thirds', async ({ page }) => { await openNavigationMenu(page); - await page.getByRole('link', { name: 'Lower Thirds' }).click(); + await page.getByRole('button', { name: 'Lower Thirds' }).click(); await expect(page).toHaveURL('http://localhost:4001/lower'); const errorBoundary = page.locator('data-testid=error-container'); await expect(errorBoundary).toHaveCount(0); @@ -44,28 +30,28 @@ test.describe('test view navigation feature', () => { test('Studio Clock', async ({ page }) => { await openNavigationMenu(page); - await page.getByRole('link', { name: 'Studio Clock' }).click(); + await page.getByRole('button', { name: 'Studio Clock' }).click(); page.locator('data-testid=studio-view'); await expect(page).toHaveURL('http://localhost:4001/studio'); }); test('Countdown', async ({ page }) => { await openNavigationMenu(page); - await page.getByRole('link', { name: 'Countdown' }).click(); + await page.getByRole('button', { name: 'Countdown' }).click(); page.locator('data-testid=countdown-view'); await expect(page).toHaveURL('http://localhost:4001/countdown'); }); test('Project Info', async ({ page }) => { await openNavigationMenu(page); - await page.getByRole('link', { name: 'Project Info' }).click(); + await page.getByRole('button', { name: 'Project Info' }).click(); page.locator('data-testid=project-view'); await expect(page).toHaveURL('http://localhost:4001/info'); }); test('Timer', async ({ page }) => { await openNavigationMenu(page); - await page.getByRole('link', { name: 'Timer', exact: true }).click(); + await page.getByRole('button', { name: 'Timer', exact: true }).click(); page.locator('data-testid=timer-view'); await expect(page).toHaveURL('http://localhost:4001/timer'); });