mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-05-23 19:47:03 -04:00
Add cypress id attribute only in test mode (#1566)
* Add function for test attribute Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de> * Adjust components Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de> * Fix naming of attribute Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de> * Rename method Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de> * Rename method, interface, attribute and use interface Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de> * Lint and format fix Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
parent
2abe40ef1d
commit
a398660c18
48 changed files with 229 additions and 167 deletions
|
@ -10,12 +10,13 @@ import type { Variant } from 'react-bootstrap/types'
|
|||
import { useTranslation } from 'react-i18next'
|
||||
import { ForkAwesomeIcon } from '../../fork-awesome/fork-awesome-icon'
|
||||
import { CopyOverlay } from '../copy-overlay'
|
||||
import type { PropsWithDataCypressId } from '../../../../utils/cypress-attribute'
|
||||
import { cypressId } from '../../../../utils/cypress-attribute'
|
||||
|
||||
export interface CopyToClipboardButtonProps {
|
||||
export interface CopyToClipboardButtonProps extends PropsWithDataCypressId {
|
||||
content: string
|
||||
size?: 'sm' | 'lg'
|
||||
variant?: Variant
|
||||
'data-cy'?: string
|
||||
}
|
||||
|
||||
export const CopyToClipboardButton: React.FC<CopyToClipboardButtonProps> = ({
|
||||
|
@ -34,7 +35,7 @@ export const CopyToClipboardButton: React.FC<CopyToClipboardButtonProps> = ({
|
|||
size={size}
|
||||
variant={variant}
|
||||
title={t('renderer.highlightCode.copyCode')}
|
||||
data-cy={props['data-cy']}>
|
||||
{...cypressId(props)}>
|
||||
<ForkAwesomeIcon icon='files-o' />
|
||||
</Button>
|
||||
<CopyOverlay content={content} clickComponent={button} />
|
||||
|
|
|
@ -10,8 +10,10 @@ import { Trans, useTranslation } from 'react-i18next'
|
|||
import { ForkAwesomeIcon } from '../fork-awesome/fork-awesome-icon'
|
||||
import type { IconName } from '../fork-awesome/types'
|
||||
import { ShowIf } from '../show-if/show-if'
|
||||
import type { PropsWithDataCypressId } from '../../../utils/cypress-attribute'
|
||||
import { cypressId } from '../../../utils/cypress-attribute'
|
||||
|
||||
export interface CommonModalProps {
|
||||
export interface CommonModalProps extends PropsWithDataCypressId {
|
||||
show: boolean
|
||||
onHide?: () => void
|
||||
titleI18nKey?: string
|
||||
|
@ -20,7 +22,6 @@ export interface CommonModalProps {
|
|||
icon?: IconName
|
||||
size?: 'lg' | 'sm' | 'xl'
|
||||
additionalClasses?: string
|
||||
'data-cy'?: string
|
||||
}
|
||||
|
||||
export const CommonModal: React.FC<CommonModalProps> = ({
|
||||
|
@ -39,7 +40,7 @@ export const CommonModal: React.FC<CommonModalProps> = ({
|
|||
|
||||
return (
|
||||
<Modal
|
||||
data-cy={props['data-cy']}
|
||||
{...cypressId(props)}
|
||||
show={show}
|
||||
onHide={onHide}
|
||||
animation={true}
|
||||
|
|
|
@ -10,6 +10,7 @@ import { CommonModal } from '../modals/common-modal'
|
|||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { useApplicationState } from '../../../hooks/common/use-application-state'
|
||||
import { dismissMotd } from '../../../redux/motd/methods'
|
||||
import { cypressId } from '../../../utils/cypress-attribute'
|
||||
|
||||
/**
|
||||
* Reads the motd from the global application state and shows it in a modal.
|
||||
|
@ -47,10 +48,10 @@ export const MotdModal: React.FC = () => {
|
|||
return null
|
||||
} else {
|
||||
return (
|
||||
<CommonModal data-cy={'motd'} show={!!motdState} titleI18nKey={'motd.title'}>
|
||||
<CommonModal {...cypressId('motd')} show={!!motdState} titleI18nKey={'motd.title'}>
|
||||
<Modal.Body>{domContent}</Modal.Body>
|
||||
<Modal.Footer>
|
||||
<Button variant={'success'} onClick={dismiss} data-cy={'motd-dismiss'}>
|
||||
<Button variant={'success'} onClick={dismiss} {...cypressId('motd-dismiss')}>
|
||||
<Trans i18nKey={'common.dismiss'} />
|
||||
</Button>
|
||||
</Modal.Footer>
|
||||
|
|
|
@ -10,6 +10,7 @@ import { useTranslation } from 'react-i18next'
|
|||
import { setEditorMode } from '../../../redux/editor/methods'
|
||||
import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon'
|
||||
import { useApplicationState } from '../../../hooks/common/use-application-state'
|
||||
import { cypressId } from '../../../utils/cypress-attribute'
|
||||
|
||||
export enum EditorMode {
|
||||
PREVIEW = 'view',
|
||||
|
@ -30,21 +31,21 @@ export const EditorViewMode: React.FC = () => {
|
|||
setEditorMode(value)
|
||||
}}>
|
||||
<ToggleButton
|
||||
data-cy={'view-mode-preview'}
|
||||
{...cypressId('view-mode-preview')}
|
||||
value={EditorMode.PREVIEW}
|
||||
variant='outline-secondary'
|
||||
title={t('editor.viewMode.view')}>
|
||||
<ForkAwesomeIcon icon='eye' />
|
||||
</ToggleButton>
|
||||
<ToggleButton
|
||||
data-cy={'view-mode-both'}
|
||||
{...cypressId('view-mode-both')}
|
||||
value={EditorMode.BOTH}
|
||||
variant='outline-secondary'
|
||||
title={t('editor.viewMode.both')}>
|
||||
<ForkAwesomeIcon icon='columns' />
|
||||
</ToggleButton>
|
||||
<ToggleButton
|
||||
data-cy={'view-mode-editor'}
|
||||
{...cypressId('view-mode-editor')}
|
||||
value={EditorMode.EDITOR}
|
||||
variant='outline-secondary'
|
||||
title={t('editor.viewMode.edit')}>
|
||||
|
|
|
@ -42,7 +42,7 @@ export const DocumentInfoLineWordCount: React.FC = () => {
|
|||
</ShowIf>
|
||||
<ShowIf condition={wordCount !== null}>
|
||||
<Trans i18nKey={'editor.modal.documentInfo.words'}>
|
||||
<UnitalicBoldText text={wordCount ?? ''} dataCy={'document-info-word-count'} />
|
||||
<UnitalicBoldText text={wordCount ?? ''} data-cypress-id={'document-info-word-count'} />
|
||||
</Trans>
|
||||
</ShowIf>
|
||||
</DocumentInfoLine>
|
||||
|
|
|
@ -14,6 +14,7 @@ import { DocumentInfoLineWithTimeMode, DocumentInfoTimeLine } from './document-i
|
|||
import { UnitalicBoldText } from './unitalic-bold-text'
|
||||
import { useCustomizeAssetsUrl } from '../../../../hooks/common/use-customize-assets-url'
|
||||
import { DocumentInfoLineWordCount } from './document-info-line-word-count'
|
||||
import { cypressId } from '../../../../utils/cypress-attribute'
|
||||
|
||||
export interface DocumentInfoModalProps {
|
||||
show: boolean
|
||||
|
@ -31,7 +32,7 @@ export const DocumentInfoModal: React.FC<DocumentInfoModalProps> = ({ show, onHi
|
|||
onHide={onHide}
|
||||
closeButton={true}
|
||||
titleI18nKey={'editor.modal.documentInfo.title'}
|
||||
data-cy={'document-info-modal'}>
|
||||
{...cypressId('document-info-modal')}>
|
||||
<Modal.Body>
|
||||
<ListGroup>
|
||||
<ListGroup.Item>
|
||||
|
|
|
@ -5,15 +5,16 @@
|
|||
*/
|
||||
|
||||
import React from 'react'
|
||||
import type { PropsWithDataCypressId } from '../../../../utils/cypress-attribute'
|
||||
import { cypressId } from '../../../../utils/cypress-attribute'
|
||||
|
||||
export interface UnitalicBoldTextProps {
|
||||
export interface UnitalicBoldTextProps extends PropsWithDataCypressId {
|
||||
text: string | number
|
||||
dataCy?: string
|
||||
}
|
||||
|
||||
export const UnitalicBoldText: React.FC<UnitalicBoldTextProps> = ({ text, dataCy }) => {
|
||||
export const UnitalicBoldText: React.FC<UnitalicBoldTextProps> = ({ text, ...props }) => {
|
||||
return (
|
||||
<b className={'font-style-normal mr-1'} data-cy={dataCy}>
|
||||
<b className={'font-style-normal mr-1'} {...cypressId(props)}>
|
||||
{text}
|
||||
</b>
|
||||
)
|
||||
|
|
|
@ -8,6 +8,7 @@ import React from 'react'
|
|||
import { Button, Modal } from 'react-bootstrap'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { CommonModal } from '../../common/modals/common-modal'
|
||||
import { cypressId } from '../../../utils/cypress-attribute'
|
||||
|
||||
export interface MaxLengthWarningModalProps {
|
||||
show: boolean
|
||||
|
@ -20,7 +21,7 @@ export const MaxLengthWarningModal: React.FC<MaxLengthWarningModalProps> = ({ sh
|
|||
|
||||
return (
|
||||
<CommonModal
|
||||
data-cy={'limitReachedModal'}
|
||||
{...cypressId('limitReachedModal')}
|
||||
show={show}
|
||||
onHide={onHide}
|
||||
titleI18nKey={'editor.error.limitReached.title'}
|
||||
|
|
|
@ -9,6 +9,7 @@ import React, { useMemo } from 'react'
|
|||
import { useTranslation } from 'react-i18next'
|
||||
import { ShowIf } from '../../../common/show-if/show-if'
|
||||
import './status-bar.scss'
|
||||
import { cypressId } from '../../../../utils/cypress-attribute'
|
||||
|
||||
export interface StatusBarInfo {
|
||||
position: Position
|
||||
|
@ -74,7 +75,7 @@ export const StatusBar: React.FC<StatusBarInfo> = ({
|
|||
<span>{t('editor.statusBar.lines', { lines: linesInDocument })}</span>
|
||||
–
|
||||
<span
|
||||
data-cy={'remainingCharacters'}
|
||||
{...cypressId('remainingCharacters')}
|
||||
title={getLengthTooltip}
|
||||
className={remainingCharacters <= 0 ? 'text-danger' : remainingCharacters <= 100 ? 'text-warning' : ''}>
|
||||
{t('editor.statusBar.length', { length: charactersInDocument })}
|
||||
|
|
|
@ -11,6 +11,7 @@ import { useTranslation } from 'react-i18next'
|
|||
import { ForkAwesomeIcon } from '../../../../common/fork-awesome/fork-awesome-icon'
|
||||
import { addEmoji } from '../utils/toolbarButtonUtils'
|
||||
import { EmojiPicker } from './emoji-picker'
|
||||
import { cypressId } from '../../../../../utils/cypress-attribute'
|
||||
|
||||
export interface EmojiPickerButtonProps {
|
||||
editor: CodeMirror.Editor
|
||||
|
@ -31,7 +32,7 @@ export const EmojiPickerButton: React.FC<EmojiPickerButtonProps> = ({ editor })
|
|||
onDismiss={() => setShowEmojiPicker(false)}
|
||||
/>
|
||||
<Button
|
||||
data-cy={'show-emoji-picker'}
|
||||
{...cypressId('show-emoji-picker')}
|
||||
variant='light'
|
||||
onClick={() => setShowEmojiPicker((old) => !old)}
|
||||
title={t('editor.editorToolbar.emoji')}>
|
||||
|
|
|
@ -11,6 +11,7 @@ import { useTranslation } from 'react-i18next'
|
|||
import { ForkAwesomeIcon } from '../../../../common/fork-awesome/fork-awesome-icon'
|
||||
import { addTable } from '../utils/toolbarButtonUtils'
|
||||
import { TablePicker } from './table-picker'
|
||||
import { cypressId } from '../../../../../utils/cypress-attribute'
|
||||
|
||||
export interface TablePickerButtonProps {
|
||||
editor: CodeMirror.Editor
|
||||
|
@ -31,7 +32,7 @@ export const TablePickerButton: React.FC<TablePickerButtonProps> = ({ editor })
|
|||
}}
|
||||
/>
|
||||
<Button
|
||||
data-cy={'show-table-overlay'}
|
||||
{...cypressId('show-table-overlay')}
|
||||
variant='light'
|
||||
onClick={() => setShowTablePicker((old) => !old)}
|
||||
title={t('editor.editorToolbar.table.title')}>
|
||||
|
|
|
@ -12,6 +12,7 @@ import { ForkAwesomeIcon } from '../../../../common/fork-awesome/fork-awesome-ic
|
|||
import { createNumberRangeArray } from '../../../../common/number-range/number-range'
|
||||
import { CustomTableSizeModal } from './custom-table-size-modal'
|
||||
import './table-picker.scss'
|
||||
import { cypressId } from '../../../../../utils/cypress-attribute'
|
||||
|
||||
export interface TablePickerProps {
|
||||
show: boolean
|
||||
|
@ -75,7 +76,7 @@ export const TablePicker: React.FC<TablePickerProps> = ({ show, onDismiss, onTab
|
|||
)}
|
||||
</div>
|
||||
<div className='d-flex justify-content-center mt-2'>
|
||||
<Button data-cy={'show-custom-table-modal'} className={'text-center'} onClick={() => setShowDialog(true)}>
|
||||
<Button {...cypressId('show-custom-table-modal')} className={'text-center'} onClick={() => setShowDialog(true)}>
|
||||
<ForkAwesomeIcon icon='table' />
|
||||
{t('editor.editorToolbar.table.customSize')}
|
||||
</Button>
|
||||
|
|
|
@ -33,6 +33,7 @@ import {
|
|||
superscriptSelection,
|
||||
underlineSelection
|
||||
} from './utils/toolbarButtonUtils'
|
||||
import { cypressId } from '../../../../utils/cypress-attribute'
|
||||
|
||||
export interface ToolBarProps {
|
||||
editor?: Editor
|
||||
|
@ -49,42 +50,42 @@ export const ToolBar: React.FC<ToolBarProps> = ({ editor }) => {
|
|||
<ButtonToolbar className='bg-light'>
|
||||
<ButtonGroup className={'mx-1 flex-wrap'}>
|
||||
<Button
|
||||
data-cy={'format-bold'}
|
||||
{...cypressId('format-bold')}
|
||||
variant='light'
|
||||
onClick={() => makeSelectionBold(editor)}
|
||||
title={t('editor.editorToolbar.bold')}>
|
||||
<ForkAwesomeIcon icon='bold' />
|
||||
</Button>
|
||||
<Button
|
||||
data-cy={'format-italic'}
|
||||
{...cypressId('format-italic')}
|
||||
variant='light'
|
||||
onClick={() => makeSelectionItalic(editor)}
|
||||
title={t('editor.editorToolbar.italic')}>
|
||||
<ForkAwesomeIcon icon='italic' />
|
||||
</Button>
|
||||
<Button
|
||||
data-cy={'format-underline'}
|
||||
{...cypressId('format-underline')}
|
||||
variant='light'
|
||||
onClick={() => underlineSelection(editor)}
|
||||
title={t('editor.editorToolbar.underline')}>
|
||||
<ForkAwesomeIcon icon='underline' />
|
||||
</Button>
|
||||
<Button
|
||||
data-cy={'format-strikethrough'}
|
||||
{...cypressId('format-strikethrough')}
|
||||
variant='light'
|
||||
onClick={() => strikeThroughSelection(editor)}
|
||||
title={t('editor.editorToolbar.strikethrough')}>
|
||||
<ForkAwesomeIcon icon='strikethrough' />
|
||||
</Button>
|
||||
<Button
|
||||
data-cy={'format-subscript'}
|
||||
{...cypressId('format-subscript')}
|
||||
variant='light'
|
||||
onClick={() => subscriptSelection(editor)}
|
||||
title={t('editor.editorToolbar.subscript')}>
|
||||
<ForkAwesomeIcon icon='subscript' />
|
||||
</Button>
|
||||
<Button
|
||||
data-cy={'format-superscript'}
|
||||
{...cypressId('format-superscript')}
|
||||
variant='light'
|
||||
onClick={() => superscriptSelection(editor)}
|
||||
title={t('editor.editorToolbar.superscript')}>
|
||||
|
@ -93,42 +94,42 @@ export const ToolBar: React.FC<ToolBarProps> = ({ editor }) => {
|
|||
</ButtonGroup>
|
||||
<ButtonGroup className={'mx-1 flex-wrap'}>
|
||||
<Button
|
||||
data-cy={'format-heading'}
|
||||
{...cypressId('format-heading')}
|
||||
variant='light'
|
||||
onClick={() => addHeaderLevel(editor)}
|
||||
title={t('editor.editorToolbar.header')}>
|
||||
<ForkAwesomeIcon icon='header' />
|
||||
</Button>
|
||||
<Button
|
||||
data-cy={'format-code-block'}
|
||||
{...cypressId('format-code-block')}
|
||||
variant='light'
|
||||
onClick={() => addCodeFences(editor)}
|
||||
title={t('editor.editorToolbar.code')}>
|
||||
<ForkAwesomeIcon icon='code' />
|
||||
</Button>
|
||||
<Button
|
||||
data-cy={'format-block-quote'}
|
||||
{...cypressId('format-block-quote')}
|
||||
variant='light'
|
||||
onClick={() => addQuotes(editor)}
|
||||
title={t('editor.editorToolbar.blockquote')}>
|
||||
<ForkAwesomeIcon icon='quote-right' />
|
||||
</Button>
|
||||
<Button
|
||||
data-cy={'format-unordered-list'}
|
||||
{...cypressId('format-unordered-list')}
|
||||
variant='light'
|
||||
onClick={() => addList(editor)}
|
||||
title={t('editor.editorToolbar.unorderedList')}>
|
||||
<ForkAwesomeIcon icon='list' />
|
||||
</Button>
|
||||
<Button
|
||||
data-cy={'format-ordered-list'}
|
||||
{...cypressId('format-ordered-list')}
|
||||
variant='light'
|
||||
onClick={() => addOrderedList(editor)}
|
||||
title={t('editor.editorToolbar.orderedList')}>
|
||||
<ForkAwesomeIcon icon='list-ol' />
|
||||
</Button>
|
||||
<Button
|
||||
data-cy={'format-check-list'}
|
||||
{...cypressId('format-check-list')}
|
||||
variant='light'
|
||||
onClick={() => addTaskList(editor)}
|
||||
title={t('editor.editorToolbar.checkList')}>
|
||||
|
@ -137,14 +138,14 @@ export const ToolBar: React.FC<ToolBarProps> = ({ editor }) => {
|
|||
</ButtonGroup>
|
||||
<ButtonGroup className={'mx-1 flex-wrap'}>
|
||||
<Button
|
||||
data-cy={'format-link'}
|
||||
{...cypressId('format-link')}
|
||||
variant='light'
|
||||
onClick={() => addLink(editor)}
|
||||
title={t('editor.editorToolbar.link')}>
|
||||
<ForkAwesomeIcon icon='link' />
|
||||
</Button>
|
||||
<Button
|
||||
data-cy={'format-image'}
|
||||
{...cypressId('format-image')}
|
||||
variant='light'
|
||||
onClick={() => addImage(editor)}
|
||||
title={t('editor.editorToolbar.image')}>
|
||||
|
@ -155,21 +156,21 @@ export const ToolBar: React.FC<ToolBarProps> = ({ editor }) => {
|
|||
<ButtonGroup className={'mx-1 flex-wrap'}>
|
||||
<TablePickerButton editor={editor} />
|
||||
<Button
|
||||
data-cy={'format-add-line'}
|
||||
{...cypressId('format-add-line')}
|
||||
variant='light'
|
||||
onClick={() => addLine(editor)}
|
||||
title={t('editor.editorToolbar.line')}>
|
||||
<ForkAwesomeIcon icon='minus' />
|
||||
</Button>
|
||||
<Button
|
||||
data-cy={'format-collapsable-block'}
|
||||
{...cypressId('format-collapsable-block')}
|
||||
variant='light'
|
||||
onClick={() => addCollapsableBlock(editor)}
|
||||
title={t('editor.editorToolbar.collapsableBlock')}>
|
||||
<ForkAwesomeIcon icon='caret-square-o-down' />
|
||||
</Button>
|
||||
<Button
|
||||
data-cy={'format-add-comment'}
|
||||
{...cypressId('format-add-comment')}
|
||||
variant='light'
|
||||
onClick={() => addComment(editor)}
|
||||
title={t('editor.editorToolbar.comment')}>
|
||||
|
|
|
@ -26,6 +26,7 @@ import { useSendScrollState } from './hooks/use-send-scroll-state'
|
|||
import { useApplicationState } from '../../../hooks/common/use-application-state'
|
||||
import { Logger } from '../../../utils/logger'
|
||||
import { useEffectOnRenderTypeChange } from './hooks/use-effect-on-render-type-change'
|
||||
import { cypressId } from '../../../utils/cypress-attribute'
|
||||
|
||||
export interface RenderIframeProps extends RendererProps {
|
||||
rendererType: RendererType
|
||||
|
@ -139,7 +140,7 @@ export const RenderIframe: React.FC<RenderIframeProps> = ({
|
|||
<CommunicatorImageLightbox />
|
||||
<iframe
|
||||
style={{ height: `${frameHeight}px` }}
|
||||
data-cy={'documentIframe'}
|
||||
{...cypressId('documentIframe')}
|
||||
onLoad={onIframeLoad}
|
||||
title='render'
|
||||
{...(isTestMode() ? {} : { sandbox: 'allow-downloads allow-same-origin allow-scripts allow-popups' })}
|
||||
|
|
|
@ -11,13 +11,14 @@ import links from '../../../links.json'
|
|||
import { TranslatedExternalLink } from '../../common/links/translated-external-link'
|
||||
import { ShowIf } from '../../common/show-if/show-if'
|
||||
import type { CommonModalProps } from '../../common/modals/common-modal'
|
||||
import { cypressId } from '../../../utils/cypress-attribute'
|
||||
|
||||
export const YamlArrayDeprecationAlert: React.FC<Partial<CommonModalProps>> = ({ show }) => {
|
||||
useTranslation()
|
||||
|
||||
return (
|
||||
<ShowIf condition={!!show}>
|
||||
<Alert data-cy={'yamlArrayDeprecationAlert'} className={'text-wrap'} variant='warning' dir='auto'>
|
||||
<Alert {...cypressId('yamlArrayDeprecationAlert')} className={'text-wrap'} variant='warning' dir='auto'>
|
||||
<span className={'text-wrap'}>
|
||||
<span className={'text-wrap'}>
|
||||
<Trans i18nKey='editor.deprecatedTags' />
|
||||
|
|
|
@ -9,6 +9,7 @@ import { Trans, useTranslation } from 'react-i18next'
|
|||
import { DocumentInfoModal } from '../document-bar/document-info/document-info-modal'
|
||||
import { SidebarButton } from './sidebar-button'
|
||||
import type { SpecificSidebarEntryProps } from './types'
|
||||
import { cypressId } from '../../../utils/cypress-attribute'
|
||||
|
||||
export const DocumentInfoSidebarEntry: React.FC<SpecificSidebarEntryProps> = ({ className, hide }) => {
|
||||
const [showModal, setShowModal] = useState(false)
|
||||
|
@ -21,7 +22,7 @@ export const DocumentInfoSidebarEntry: React.FC<SpecificSidebarEntryProps> = ({
|
|||
className={className}
|
||||
icon={'line-chart'}
|
||||
onClick={() => setShowModal(true)}
|
||||
data-cy={'sidebar-btn-document-info'}>
|
||||
{...cypressId('sidebar-btn-document-info')}>
|
||||
<Trans i18nKey={'editor.modal.documentInfo.title'} />
|
||||
</SidebarButton>
|
||||
<DocumentInfoModal show={showModal} onHide={() => setShowModal(false)} />
|
||||
|
|
|
@ -11,6 +11,7 @@ import { Trans, useTranslation } from 'react-i18next'
|
|||
import { download } from '../../common/download/download'
|
||||
import { SidebarButton } from './sidebar-button'
|
||||
import { useNoteMarkdownContent } from '../../../hooks/common/use-note-markdown-content'
|
||||
import { cypressId } from '../../../utils/cypress-attribute'
|
||||
|
||||
export const ExportMarkdownSidebarEntry: React.FC = () => {
|
||||
const { t } = useTranslation()
|
||||
|
@ -21,7 +22,7 @@ export const ExportMarkdownSidebarEntry: React.FC = () => {
|
|||
}, [markdownContent, t])
|
||||
|
||||
return (
|
||||
<SidebarButton data-cy={'menu-export-markdown'} onClick={onClick} icon={'file-text'}>
|
||||
<SidebarButton {...cypressId('menu-export-markdown')} onClick={onClick} icon={'file-text'}>
|
||||
<Trans i18nKey={'editor.export.markdown-file'} />
|
||||
</SidebarButton>
|
||||
)
|
||||
|
|
|
@ -12,6 +12,7 @@ import { SidebarButton } from './sidebar-button'
|
|||
import { SidebarMenu } from './sidebar-menu'
|
||||
import type { SpecificSidebarMenuProps } from './types'
|
||||
import { DocumentSidebarMenuSelection } from './types'
|
||||
import { cypressId } from '../../../utils/cypress-attribute'
|
||||
|
||||
export const ExportMenuSidebarMenu: React.FC<SpecificSidebarMenuProps> = ({
|
||||
className,
|
||||
|
@ -30,7 +31,7 @@ export const ExportMenuSidebarMenu: React.FC<SpecificSidebarMenuProps> = ({
|
|||
return (
|
||||
<Fragment>
|
||||
<SidebarButton
|
||||
data-cy={'menu-export'}
|
||||
{...cypressId('menu-export')}
|
||||
hide={hide}
|
||||
icon={expand ? 'arrow-left' : 'cloud-download'}
|
||||
className={className}
|
||||
|
|
|
@ -10,6 +10,7 @@ import { useNoteMarkdownContent } from '../../../hooks/common/use-note-markdown-
|
|||
import { setNoteContent } from '../../../redux/note-details/methods'
|
||||
import { SidebarButton } from './sidebar-button'
|
||||
import { UploadInput } from './upload-input'
|
||||
import { cypressId } from '../../../utils/cypress-attribute'
|
||||
|
||||
export const ImportMarkdownSidebarEntry: React.FC = () => {
|
||||
const markdownContent = useNoteMarkdownContent()
|
||||
|
@ -42,12 +43,12 @@ export const ImportMarkdownSidebarEntry: React.FC = () => {
|
|||
|
||||
return (
|
||||
<Fragment>
|
||||
<SidebarButton data-cy={'menu-import-markdown'} icon={'file-text-o'} onClick={buttonClick}>
|
||||
<SidebarButton {...cypressId('menu-import-markdown')} icon={'file-text-o'} onClick={buttonClick}>
|
||||
<Trans i18nKey={'editor.import.file'} />
|
||||
</SidebarButton>
|
||||
<UploadInput
|
||||
onLoad={onImportMarkdown}
|
||||
data-cy={'menu-import-markdown-input'}
|
||||
{...cypressId('menu-import-markdown-input')}
|
||||
acceptedFiles={'.md, text/markdown, text/plain'}
|
||||
onClickRef={clickRef}
|
||||
/>
|
||||
|
|
|
@ -11,6 +11,7 @@ import { SidebarButton } from './sidebar-button'
|
|||
import { SidebarMenu } from './sidebar-menu'
|
||||
import type { SpecificSidebarMenuProps } from './types'
|
||||
import { DocumentSidebarMenuSelection } from './types'
|
||||
import { cypressId } from '../../../utils/cypress-attribute'
|
||||
|
||||
export const ImportMenuSidebarMenu: React.FC<SpecificSidebarMenuProps> = ({
|
||||
className,
|
||||
|
@ -29,7 +30,7 @@ export const ImportMenuSidebarMenu: React.FC<SpecificSidebarMenuProps> = ({
|
|||
return (
|
||||
<Fragment>
|
||||
<SidebarButton
|
||||
data-cy={'menu-import'}
|
||||
{...cypressId('menu-import')}
|
||||
hide={hide}
|
||||
icon={expand ? 'arrow-left' : 'cloud-upload'}
|
||||
className={className}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
import type { RefObject } from 'react'
|
||||
import type { IconName } from '../../common/fork-awesome/types'
|
||||
import type { SidebarEntryVariant } from './sidebar-button'
|
||||
import type { PropsWithDataCypressId } from '../../../utils/cypress-attribute'
|
||||
|
||||
export interface SpecificSidebarEntryProps {
|
||||
className?: string
|
||||
|
@ -14,14 +15,13 @@ export interface SpecificSidebarEntryProps {
|
|||
onClick?: () => void
|
||||
}
|
||||
|
||||
export interface SidebarEntryProps {
|
||||
export interface SidebarEntryProps extends PropsWithDataCypressId {
|
||||
icon?: IconName
|
||||
variant?: SidebarEntryVariant
|
||||
buttonRef?: RefObject<HTMLButtonElement>
|
||||
hide?: boolean
|
||||
className?: string
|
||||
onClick?: () => void
|
||||
'data-cy'?: string
|
||||
}
|
||||
|
||||
export interface SidebarMenuProps {
|
||||
|
|
|
@ -7,14 +7,15 @@
|
|||
import type { MutableRefObject } from 'react'
|
||||
import React, { useCallback, useEffect, useRef } from 'react'
|
||||
import { Logger } from '../../../utils/logger'
|
||||
import type { PropsWithDataCypressId } from '../../../utils/cypress-attribute'
|
||||
import { cypressId } from '../../../utils/cypress-attribute'
|
||||
|
||||
const log = new Logger('UploadInput')
|
||||
|
||||
export interface UploadInputProps {
|
||||
export interface UploadInputProps extends PropsWithDataCypressId {
|
||||
onLoad: (file: File) => Promise<void>
|
||||
acceptedFiles: string
|
||||
onClickRef: MutableRefObject<(() => void) | undefined>
|
||||
'data-cy'?: string
|
||||
}
|
||||
|
||||
export const UploadInput: React.FC<UploadInputProps> = ({ onLoad, acceptedFiles, onClickRef, ...props }) => {
|
||||
|
@ -44,7 +45,5 @@ export const UploadInput: React.FC<UploadInputProps> = ({ onLoad, acceptedFiles,
|
|||
onClickRef.current = onClick
|
||||
})
|
||||
|
||||
return (
|
||||
<input data-cy={props['data-cy']} type='file' ref={fileInputReference} className='d-none' accept={acceptedFiles} />
|
||||
)
|
||||
return <input {...cypressId(props)} type='file' ref={fileInputReference} className='d-none' accept={acceptedFiles} />
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import { useApplicationState } from '../../../hooks/common/use-application-state
|
|||
import { ShowIf } from '../../common/show-if/show-if'
|
||||
import { SignInButton } from '../../landing-layout/navigation/sign-in-button'
|
||||
import './cover-buttons.scss'
|
||||
import { cypressId } from '../../../utils/cypress-attribute'
|
||||
|
||||
export const CoverButtons: React.FC = () => {
|
||||
useTranslation()
|
||||
|
@ -33,7 +34,7 @@ export const CoverButtons: React.FC = () => {
|
|||
</span>
|
||||
</ShowIf>
|
||||
<Link to='/n/features'>
|
||||
<Button data-cy={'features-button'} className='cover-button' variant='primary' size='lg'>
|
||||
<Button {...cypressId('features-button')} className='cover-button' variant='primary' size='lg'>
|
||||
<Trans i18nKey='landing.intro.exploreFeatures' />
|
||||
</Button>
|
||||
</Link>
|
||||
|
|
|
@ -8,6 +8,7 @@ import React, { Fragment, useCallback, useState } from 'react'
|
|||
import { Trans } from 'react-i18next'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { VersionInfoModal } from './version-info-modal'
|
||||
import { cypressId } from '../../../../utils/cypress-attribute'
|
||||
|
||||
export const VersionInfoLink: React.FC = () => {
|
||||
const [show, setShow] = useState(false)
|
||||
|
@ -16,7 +17,7 @@ export const VersionInfoLink: React.FC = () => {
|
|||
|
||||
return (
|
||||
<Fragment>
|
||||
<Link data-cy={'show-version-modal'} to={'#'} className={'text-light'} onClick={showModal}>
|
||||
<Link {...cypressId('show-version-modal')} to={'#'} className={'text-light'} onClick={showModal}>
|
||||
<Trans i18nKey={'landing.versionInfo.versionInfo'} />
|
||||
</Link>
|
||||
<VersionInfoModal onHide={closeModal} show={show} />
|
||||
|
|
|
@ -13,6 +13,7 @@ import frontendVersion from '../../../../version.json'
|
|||
import links from '../../../../links.json'
|
||||
import type { BackendVersion } from '../../../../api/config/types'
|
||||
import { useApplicationState } from '../../../../hooks/common/use-application-state'
|
||||
import { cypressId } from '../../../../utils/cypress-attribute'
|
||||
|
||||
export const VersionInfoModal: React.FC<CommonModalProps> = ({ onHide, show }) => {
|
||||
const serverVersion: BackendVersion = useApplicationState((state) => state.config.version)
|
||||
|
@ -31,7 +32,7 @@ export const VersionInfoModal: React.FC<CommonModalProps> = ({ onHide, show }) =
|
|||
|
||||
return (
|
||||
<CommonModal
|
||||
data-cy={'version-modal'}
|
||||
{...cypressId('version-modal')}
|
||||
show={show}
|
||||
onHide={onHide}
|
||||
closeButton={true}
|
||||
|
|
|
@ -13,6 +13,7 @@ import { ShowIf } from '../../common/show-if/show-if'
|
|||
import { getApiUrl } from '../../../api/utils'
|
||||
import { INTERACTIVE_LOGIN_METHODS } from '../../../api/auth'
|
||||
import { useApplicationState } from '../../../hooks/common/use-application-state'
|
||||
import { cypressId } from '../../../utils/cypress-attribute'
|
||||
|
||||
export type SignInButtonProps = Omit<ButtonProps, 'href'>
|
||||
|
||||
|
@ -36,7 +37,7 @@ export const SignInButton: React.FC<SignInButtonProps> = ({ variant, ...props })
|
|||
return (
|
||||
<ShowIf condition={authEnabled}>
|
||||
<LinkContainer to={loginLink} title={t('login.signIn')}>
|
||||
<Button data-cy={'sign-in-button'} variant={variant || 'success'} {...props}>
|
||||
<Button {...cypressId('sign-in-button')} variant={variant || 'success'} {...props}>
|
||||
<Trans i18nKey='login.signIn' />
|
||||
</Button>
|
||||
</LinkContainer>
|
||||
|
|
|
@ -8,6 +8,7 @@ import React from 'react'
|
|||
import { Alert } from 'react-bootstrap'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { useApplicationState } from '../../hooks/common/use-application-state'
|
||||
import { cypressId } from '../../utils/cypress-attribute'
|
||||
import { ShowIf } from '../common/show-if/show-if'
|
||||
import type { SimpleAlertProps } from '../common/simple-alert/simple-alert-props'
|
||||
|
||||
|
@ -18,7 +19,7 @@ export const DocumentLengthLimitReachedAlert: React.FC<SimpleAlertProps> = ({ sh
|
|||
|
||||
return (
|
||||
<ShowIf condition={show}>
|
||||
<Alert variant='danger' dir={'auto'} data-cy={'limitReachedMessage'}>
|
||||
<Alert variant='danger' dir={'auto'} {...cypressId('limitReachedMessage')}>
|
||||
<Trans i18nKey={'editor.error.limitReached.description'} values={{ maxLength }} />
|
||||
</Alert>
|
||||
</ShowIf>
|
||||
|
|
|
@ -9,6 +9,7 @@ import { Alert } from 'react-bootstrap'
|
|||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { useIsDarkModeActivated } from '../../../../../hooks/common/use-is-dark-mode-activated'
|
||||
import { Logger } from '../../../../../utils/logger'
|
||||
import { cypressId } from '../../../../../utils/cypress-attribute'
|
||||
|
||||
const log = new Logger('FlowChart')
|
||||
|
||||
|
@ -60,6 +61,6 @@ export const FlowChart: React.FC<FlowChartProps> = ({ code }) => {
|
|||
</Alert>
|
||||
)
|
||||
} else {
|
||||
return <div ref={diagramRef} data-cy={'flowchart'} className={'text-center'} />
|
||||
return <div ref={diagramRef} {...cypressId('flowchart')} className={'text-center'} />
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
import React, { useCallback } from 'react'
|
||||
import { cypressId } from '../../../../utils/cypress-attribute'
|
||||
import './gist-frame.scss'
|
||||
import { useResizeGistFrame } from './use-resize-gist-frame'
|
||||
|
||||
|
@ -31,7 +32,7 @@ export const GistFrame: React.FC<GistFrameProps> = ({ id }) => {
|
|||
<span>
|
||||
<iframe
|
||||
sandbox=''
|
||||
data-cy={'gh-gist'}
|
||||
{...cypressId('gh-gist')}
|
||||
width='100%'
|
||||
height={`${frameHeight}px`}
|
||||
frameBorder='0'
|
||||
|
|
|
@ -9,6 +9,7 @@ import { Alert } from 'react-bootstrap'
|
|||
import { ShowIf } from '../../../common/show-if/show-if'
|
||||
import { useFrontendBaseUrl } from '../../../../hooks/common/use-frontend-base-url'
|
||||
import { Logger } from '../../../../utils/logger'
|
||||
import { cypressId } from '../../../../utils/cypress-attribute'
|
||||
|
||||
const log = new Logger('GraphvizFrame')
|
||||
|
||||
|
@ -66,7 +67,7 @@ export const GraphvizFrame: React.FC<GraphvizFrameProps> = ({ code }) => {
|
|||
<ShowIf condition={!!error}>
|
||||
<Alert variant={'warning'}>{error}</Alert>
|
||||
</ShowIf>
|
||||
<div className={'svg-container'} data-cy={'graphviz'} ref={container} />
|
||||
<div className={'svg-container'} {...cypressId('graphviz')} ref={container} />
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import { CopyToClipboardButton } from '../../../../common/copyable/copy-to-clipb
|
|||
import '../../../utils/button-inside.scss'
|
||||
import './highlighted-code.scss'
|
||||
import { Logger } from '../../../../../utils/logger'
|
||||
import { cypressId } from '../../../../../utils/cypress-attribute'
|
||||
|
||||
const log = new Logger('HighlightedCode')
|
||||
|
||||
|
@ -70,7 +71,7 @@ export const HighlightedCode: React.FC<HighlightedCodeProps> = ({ code, language
|
|||
{dom}
|
||||
</code>
|
||||
<div className={'text-right button-inside'}>
|
||||
<CopyToClipboardButton content={code} data-cy='copy-code-button' />
|
||||
<CopyToClipboardButton content={code} {...cypressId('copy-code-button')} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -9,6 +9,7 @@ import { useTranslation } from 'react-i18next'
|
|||
import { LockButton } from '../../../common/lock-button/lock-button'
|
||||
import '../../utils/button-inside.scss'
|
||||
import { Logger } from '../../../../utils/logger'
|
||||
import { cypressId } from '../../../../utils/cypress-attribute'
|
||||
|
||||
const log = new Logger('MarkmapFrame')
|
||||
|
||||
|
@ -66,7 +67,7 @@ export const MarkmapFrame: React.FC<MarkmapFrameProps> = ({ code }) => {
|
|||
}, [code])
|
||||
|
||||
return (
|
||||
<div data-cy={'markmap'} className={'position-relative'}>
|
||||
<div {...cypressId('markmap')} className={'position-relative'}>
|
||||
<div className={'svg-container'} ref={diagramContainer} />
|
||||
<div className={'text-right button-inside'}>
|
||||
<LockButton
|
||||
|
|
|
@ -8,13 +8,14 @@ import React from 'react'
|
|||
import { Alert } from 'react-bootstrap'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import links from '../../../../links.json'
|
||||
import { cypressId } from '../../../../utils/cypress-attribute'
|
||||
import { TranslatedExternalLink } from '../../../common/links/translated-external-link'
|
||||
|
||||
export const DeprecationWarning: React.FC = () => {
|
||||
useTranslation()
|
||||
|
||||
return (
|
||||
<Alert data-cy={'yaml'} className={'mt-2'} variant={'warning'}>
|
||||
<Alert {...cypressId('yaml')} className={'mt-2'} variant={'warning'}>
|
||||
<span className={'text-wrap'}>
|
||||
<Trans i18nKey={'renderer.sequence.deprecationWarning'} />
|
||||
</span>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue