mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-05-22 11:15:23 -04:00
Cypress-IDs and prettier for tests (#1634)
* Add cy.getById method and run prettier Signed-off-by: Erik Michelson <github@erik.michelson.eu>
This commit is contained in:
parent
8a8bacc0aa
commit
d725b65140
53 changed files with 758 additions and 1203 deletions
|
@ -22,12 +22,13 @@ export const DeletionModal: React.FC<DeletionModalProps> = ({
|
|||
onConfirm,
|
||||
deletionButtonI18nKey,
|
||||
icon,
|
||||
children
|
||||
children,
|
||||
...props
|
||||
}) => {
|
||||
useTranslation()
|
||||
|
||||
return (
|
||||
<CommonModal show={show} onHide={onHide} titleI18nKey={titleI18nKey} icon={icon} closeButton={true}>
|
||||
<CommonModal show={show} onHide={onHide} titleI18nKey={titleI18nKey} icon={icon} closeButton={true} {...props}>
|
||||
<Modal.Body className='text-dark'>{children}</Modal.Body>
|
||||
<Modal.Footer>
|
||||
<Button variant='danger' onClick={onConfirm}>
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import React from 'react'
|
||||
import { Modal } from 'react-bootstrap'
|
||||
import type { CommonModalProps } from './common-modal'
|
||||
import { CommonModal } from './common-modal'
|
||||
|
||||
export const ErrorModal: React.FC<CommonModalProps> = ({ show, onHide, titleI18nKey, icon, children }) => {
|
||||
return (
|
||||
<CommonModal show={show} onHide={onHide} titleI18nKey={titleI18nKey} icon={icon} closeButton={true}>
|
||||
<Modal.Body className='text-dark text-center'>{children}</Modal.Body>
|
||||
</CommonModal>
|
||||
)
|
||||
}
|
|
@ -9,6 +9,7 @@ import { Button } from 'react-bootstrap'
|
|||
import { useTranslation } from 'react-i18next'
|
||||
import { ForkAwesomeIcon } from '../../../common/fork-awesome/fork-awesome-icon'
|
||||
import { HelpModal } from './help-modal'
|
||||
import { cypressId } from '../../../../utils/cypress-attribute'
|
||||
|
||||
export const HelpButton: React.FC = () => {
|
||||
const { t } = useTranslation()
|
||||
|
@ -18,6 +19,7 @@ export const HelpButton: React.FC = () => {
|
|||
return (
|
||||
<Fragment>
|
||||
<Button
|
||||
{...cypressId('editor-help-button')}
|
||||
title={t('editor.documentBar.help')}
|
||||
className='ml-2 text-secondary'
|
||||
size='sm'
|
||||
|
|
|
@ -12,6 +12,7 @@ import { ForkAwesomeIcon } from '../../../common/fork-awesome/fork-awesome-icon'
|
|||
import { UploadInput } from '../../sidebar/upload-input'
|
||||
import { handleUpload } from '../upload-handler'
|
||||
import { supportedMimeTypes } from '../../../common/upload-image-mimetypes'
|
||||
import { cypressId } from '../../../../utils/cypress-attribute'
|
||||
|
||||
export interface UploadImageButtonProps {
|
||||
editor?: Editor
|
||||
|
@ -42,10 +43,19 @@ export const UploadImageButton: React.FC<UploadImageButtonProps> = ({ editor })
|
|||
|
||||
return (
|
||||
<Fragment>
|
||||
<Button variant='light' onClick={buttonClick} title={t('editor.editorToolbar.uploadImage')}>
|
||||
<Button
|
||||
variant='light'
|
||||
onClick={buttonClick}
|
||||
title={t('editor.editorToolbar.uploadImage')}
|
||||
{...cypressId('editor-toolbar-upload-image-button')}>
|
||||
<ForkAwesomeIcon icon={'upload'} />
|
||||
</Button>
|
||||
<UploadInput onLoad={onUploadImage} acceptedFiles={acceptedMimeTypes} onClickRef={clickRef} />
|
||||
<UploadInput
|
||||
onLoad={onUploadImage}
|
||||
acceptedFiles={acceptedMimeTypes}
|
||||
onClickRef={clickRef}
|
||||
{...cypressId('editor-toolbar-upload-image-input')}
|
||||
/>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ export const HistoryCard: React.FC<HistoryEntryProps & HistoryEventHandlers> = (
|
|||
const entryTitle = useHistoryEntryTitle(entry)
|
||||
|
||||
return (
|
||||
<div className='p-2 col-xs-12 col-sm-6 col-md-6 col-lg-4'>
|
||||
<div className='p-2 col-xs-12 col-sm-6 col-md-6 col-lg-4' {...cypressId('history-card')}>
|
||||
<Card className='card-min-height' text={'dark'} bg={'light'}>
|
||||
<Card.Body className='p-2 d-flex flex-row justify-content-between'>
|
||||
<div className={'d-flex flex-column'}>
|
||||
|
|
|
@ -8,6 +8,7 @@ import React from 'react'
|
|||
import { Button } from 'react-bootstrap'
|
||||
import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon'
|
||||
import './pin-button.scss'
|
||||
import { cypressId } from '../../../utils/cypress-attribute'
|
||||
|
||||
export interface PinButtonProps {
|
||||
isPinned: boolean
|
||||
|
@ -21,7 +22,8 @@ export const PinButton: React.FC<PinButtonProps> = ({ isPinned, onPinClick, isDa
|
|||
<Button
|
||||
variant={isDark ? 'secondary' : 'light'}
|
||||
className={`history-pin ${className || ''} ${isPinned ? 'pinned' : ''}`}
|
||||
onClick={onPinClick}>
|
||||
onClick={onPinClick}
|
||||
{...cypressId('history-entry-pin-button')}>
|
||||
<ForkAwesomeIcon icon='thumb-tack' />
|
||||
</Button>
|
||||
)
|
||||
|
|
|
@ -9,6 +9,7 @@ import React, { useCallback, useMemo } from 'react'
|
|||
import { Form } from 'react-bootstrap'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Logger } from '../../../utils/logger'
|
||||
import { cypressId } from '../../../utils/cypress-attribute'
|
||||
|
||||
const log = new Logger('LanguagePicker')
|
||||
const languages = {
|
||||
|
@ -81,7 +82,13 @@ export const LanguagePicker: React.FC = () => {
|
|||
)
|
||||
|
||||
return (
|
||||
<Form.Control as='select' size='sm' className='mb-2 mx-auto w-auto' value={languageCode} onChange={onChangeLang}>
|
||||
<Form.Control
|
||||
as='select'
|
||||
size='sm'
|
||||
className='mb-2 mx-auto w-auto'
|
||||
value={languageCode}
|
||||
onChange={onChangeLang}
|
||||
{...cypressId('language-picker')}>
|
||||
{languageOptions}
|
||||
</Form.Control>
|
||||
)
|
||||
|
|
|
@ -14,6 +14,7 @@ import { NewUserNoteButton } from '../new-user-note-button'
|
|||
import { SignInButton } from '../sign-in-button'
|
||||
import { UserDropdown } from '../user-dropdown'
|
||||
import './header-bar.scss'
|
||||
import { cypressId } from '../../../../utils/cypress-attribute'
|
||||
|
||||
const HeaderBar: React.FC = () => {
|
||||
useTranslation()
|
||||
|
@ -22,10 +23,10 @@ const HeaderBar: React.FC = () => {
|
|||
return (
|
||||
<Navbar className='justify-content-between'>
|
||||
<div className='nav header-nav'>
|
||||
<HeaderNavLink to='/intro' id='navLinkIntro'>
|
||||
<HeaderNavLink to='/intro' {...cypressId('navLinkIntro')}>
|
||||
<Trans i18nKey='landing.navigation.intro' />
|
||||
</HeaderNavLink>
|
||||
<HeaderNavLink to='/history' id='navLinkHistory'>
|
||||
<HeaderNavLink to='/history' {...cypressId('navLinkHistory')}>
|
||||
<Trans i18nKey='landing.navigation.history' />
|
||||
</HeaderNavLink>
|
||||
</div>
|
||||
|
|
|
@ -7,17 +7,18 @@
|
|||
import React from 'react'
|
||||
import { Nav } from 'react-bootstrap'
|
||||
import { LinkContainer } from 'react-router-bootstrap'
|
||||
import type { PropsWithDataCypressId } from '../../../utils/cypress-attribute'
|
||||
import { cypressId } from '../../../utils/cypress-attribute'
|
||||
|
||||
export interface HeaderNavLinkProps {
|
||||
export interface HeaderNavLinkProps extends PropsWithDataCypressId {
|
||||
to: string
|
||||
id: string
|
||||
}
|
||||
|
||||
export const HeaderNavLink: React.FC<HeaderNavLinkProps> = ({ to, id, children }) => {
|
||||
export const HeaderNavLink: React.FC<HeaderNavLinkProps> = ({ to, children, ...props }) => {
|
||||
return (
|
||||
<Nav.Item>
|
||||
<LinkContainer to={to}>
|
||||
<Nav.Link id={id} className='text-light' href={to}>
|
||||
<Nav.Link className='text-light' href={to} {...cypressId(props)}>
|
||||
{children}
|
||||
</Nav.Link>
|
||||
</LinkContainer>
|
||||
|
|
|
@ -9,12 +9,17 @@ import { Button } from 'react-bootstrap'
|
|||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { LinkContainer } from 'react-router-bootstrap'
|
||||
import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon'
|
||||
import { cypressId } from '../../../utils/cypress-attribute'
|
||||
|
||||
export const NewGuestNoteButton: React.FC = () => {
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<LinkContainer to={'/new'} title={t('landing.navigation.newGuestNote')}>
|
||||
<Button variant='primary' size='sm' className='d-inline-flex align-items-center'>
|
||||
<Button
|
||||
variant='primary'
|
||||
size='sm'
|
||||
className='d-inline-flex align-items-center'
|
||||
{...cypressId('new-guest-note-button')}>
|
||||
<ForkAwesomeIcon icon='plus' className='mx-1' />
|
||||
<span>
|
||||
<Trans i18nKey='landing.navigation.newGuestNote' />
|
||||
|
|
|
@ -9,12 +9,17 @@ import { Button } from 'react-bootstrap'
|
|||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { LinkContainer } from 'react-router-bootstrap'
|
||||
import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon'
|
||||
import { cypressId } from '../../../utils/cypress-attribute'
|
||||
|
||||
export const NewUserNoteButton: React.FC = () => {
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<LinkContainer to={'/new'} title={t('landing.navigation.newNote')}>
|
||||
<Button variant='primary' size='sm' className='d-inline-flex align-items-center'>
|
||||
<Button
|
||||
variant='primary'
|
||||
size='sm'
|
||||
className='d-inline-flex align-items-center'
|
||||
{...cypressId('new-note-button')}>
|
||||
<ForkAwesomeIcon icon='plus' className='mx-1' />
|
||||
<span>
|
||||
<Trans i18nKey='landing.navigation.newNote' />
|
||||
|
|
|
@ -12,6 +12,7 @@ import { clearUser } from '../../../redux/user/methods'
|
|||
import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon'
|
||||
import { UserAvatar } from '../../common/user-avatar/user-avatar'
|
||||
import { useApplicationState } from '../../../hooks/common/use-application-state'
|
||||
import { cypressId } from '../../../utils/cypress-attribute'
|
||||
|
||||
export const UserDropdown: React.FC = () => {
|
||||
useTranslation()
|
||||
|
@ -23,19 +24,19 @@ export const UserDropdown: React.FC = () => {
|
|||
|
||||
return (
|
||||
<Dropdown alignRight>
|
||||
<Dropdown.Toggle size='sm' variant='dark' id='dropdown-user' className={'d-flex align-items-center'}>
|
||||
<Dropdown.Toggle size='sm' variant='dark' {...cypressId('user-dropdown')} className={'d-flex align-items-center'}>
|
||||
<UserAvatar name={user.name} photo={user.photo} />
|
||||
</Dropdown.Toggle>
|
||||
|
||||
<Dropdown.Menu className='text-start'>
|
||||
<LinkContainer to={'/n/features'}>
|
||||
<Dropdown.Item dir='auto'>
|
||||
<Dropdown.Item dir='auto' {...cypressId('user-dropdown-features-button')}>
|
||||
<ForkAwesomeIcon icon='bolt' fixedWidth={true} className='mx-2' />
|
||||
<Trans i18nKey='editor.help.documents.features' />
|
||||
</Dropdown.Item>
|
||||
</LinkContainer>
|
||||
<LinkContainer to={'/profile'}>
|
||||
<Dropdown.Item dir='auto'>
|
||||
<Dropdown.Item dir='auto' {...cypressId('user-dropdown-profile-button')}>
|
||||
<ForkAwesomeIcon icon='user' fixedWidth={true} className='mx-2' />
|
||||
<Trans i18nKey='profile.userProfile' />
|
||||
</Dropdown.Item>
|
||||
|
@ -44,7 +45,8 @@ export const UserDropdown: React.FC = () => {
|
|||
dir='auto'
|
||||
onClick={() => {
|
||||
clearUser()
|
||||
}}>
|
||||
}}
|
||||
{...cypressId('user-dropdown-sign-out-button')}>
|
||||
<ForkAwesomeIcon icon='sign-out' fixedWidth={true} className='mx-2' />
|
||||
<Trans i18nKey='login.signOut' />
|
||||
</Dropdown.Item>
|
||||
|
|
|
@ -8,6 +8,7 @@ import React, { useEffect, useRef } from 'react'
|
|||
import './abc.scss'
|
||||
import { Logger } from '../../../../utils/logger'
|
||||
import type { CodeProps } from '../../replace-components/code-block-component-replacer'
|
||||
import { cypressId } from '../../../../utils/cypress-attribute'
|
||||
|
||||
const log = new Logger('AbcFrame')
|
||||
|
||||
|
@ -28,5 +29,5 @@ export const AbcFrame: React.FC<CodeProps> = ({ code }) => {
|
|||
})
|
||||
}, [code])
|
||||
|
||||
return <div ref={container} className={'abcjs-score bg-white text-black svg-container'} />
|
||||
return <div ref={container} className={'abcjs-score bg-white text-black svg-container'} {...cypressId('abcjs')} />
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
import React, { useMemo } from 'react'
|
||||
import { parseCsv } from './csv-parser'
|
||||
import { cypressId } from '../../../../utils/cypress-attribute'
|
||||
|
||||
export interface CsvTableProps {
|
||||
code: string
|
||||
|
@ -63,7 +64,7 @@ export const CsvTable: React.FC<CsvTableProps> = ({
|
|||
)
|
||||
|
||||
return (
|
||||
<table className={'csv-html-table table-striped'}>
|
||||
<table className={'csv-html-table table-striped'} {...cypressId('csv-html-table')}>
|
||||
{renderTableHeader}
|
||||
{renderTableBody}
|
||||
</table>
|
||||
|
|
|
@ -66,7 +66,7 @@ export const HighlightedCode: React.FC<HighlightedCodeProps> = ({ code, language
|
|||
}, [code, language, startLineNumber])
|
||||
|
||||
return (
|
||||
<div className={'code-highlighter'}>
|
||||
<div className={'code-highlighter'} {...cypressId('highlighted-code-block')}>
|
||||
<code className={`hljs ${startLineNumber !== undefined ? 'showGutter' : ''} ${wrapLines ? 'wrapLines' : ''}`}>
|
||||
{dom}
|
||||
</code>
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
import { MarkdownExtension } from '../markdown-extension'
|
||||
import type MarkdownIt from 'markdown-it'
|
||||
import plantuml from 'markdown-it-plantuml'
|
||||
import type Renderer from 'markdown-it/lib/renderer'
|
||||
import type { RenderRule } from 'markdown-it/lib/renderer'
|
||||
import type Renderer from 'markdown-it/lib/renderer'
|
||||
import type Token from 'markdown-it/lib/token'
|
||||
import type { Options } from 'markdown-it/lib'
|
||||
import type { ComponentReplacer } from '../../replace-components/component-replacer'
|
||||
|
|
|
@ -14,9 +14,9 @@ import type { AccessToken } from '../../../api/tokens/types'
|
|||
import { CopyableField } from '../../common/copyable/copyable-field/copyable-field'
|
||||
import { IconButton } from '../../common/icon-button/icon-button'
|
||||
import { CommonModal } from '../../common/modals/common-modal'
|
||||
import { DeletionModal } from '../../common/modals/deletion-modal'
|
||||
import { ShowIf } from '../../common/show-if/show-if'
|
||||
import { Logger } from '../../../utils/logger'
|
||||
import { cypressId } from '../../../utils/cypress-attribute'
|
||||
|
||||
const log = new Logger('ProfileAccessTokens')
|
||||
|
||||
|
@ -108,7 +108,9 @@ export const ProfileAccessTokens: React.FC = () => {
|
|||
return (
|
||||
<ListGroup.Item className='bg-dark' key={token.created}>
|
||||
<Row>
|
||||
<Col className='text-start'>{token.label}</Col>
|
||||
<Col className='text-start' {...cypressId('access-token-label')}>
|
||||
{token.label}
|
||||
</Col>
|
||||
<Col className='text-start text-white-50'>
|
||||
<Trans
|
||||
i18nKey='profile.accessTokens.created'
|
||||
|
@ -120,7 +122,12 @@ export const ProfileAccessTokens: React.FC = () => {
|
|||
/>
|
||||
</Col>
|
||||
<Col xs='auto'>
|
||||
<IconButton icon='trash-o' variant='danger' onClick={() => selectForDeletion(token.created)} />
|
||||
<IconButton
|
||||
icon='trash-o'
|
||||
variant='danger'
|
||||
onClick={() => selectForDeletion(token.created)}
|
||||
{...cypressId('access-token-delete-button')}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
</ListGroup.Item>
|
||||
|
@ -140,10 +147,16 @@ export const ProfileAccessTokens: React.FC = () => {
|
|||
onChange={(event: ChangeEvent<HTMLInputElement>) => setNewTokenLabel(event.target.value)}
|
||||
isValid={newTokenSubmittable}
|
||||
required
|
||||
{...cypressId('access-token-add-input')}
|
||||
/>
|
||||
</Col>
|
||||
<Col xs={'auto'}>
|
||||
<Button type='submit' variant='primary' size='sm' disabled={!newTokenSubmittable}>
|
||||
<Button
|
||||
type='submit'
|
||||
variant='primary'
|
||||
size='sm'
|
||||
disabled={!newTokenSubmittable}
|
||||
{...cypressId('access-token-add-button')}>
|
||||
<Trans i18nKey='profile.accessTokens.createToken' />
|
||||
</Button>
|
||||
</Col>
|
||||
|
@ -155,7 +168,8 @@ export const ProfileAccessTokens: React.FC = () => {
|
|||
<CommonModal
|
||||
show={showAddedModal}
|
||||
onHide={() => setShowAddedModal(false)}
|
||||
titleI18nKey='profile.modal.addedAccessToken.title'>
|
||||
titleI18nKey='profile.modal.addedAccessToken.title'
|
||||
{...cypressId('access-token-modal-add')}>
|
||||
<Modal.Body>
|
||||
<Trans i18nKey='profile.modal.addedAccessToken.message' />
|
||||
<br />
|
||||
|
@ -168,14 +182,20 @@ export const ProfileAccessTokens: React.FC = () => {
|
|||
</Modal.Footer>
|
||||
</CommonModal>
|
||||
|
||||
<DeletionModal
|
||||
onConfirm={deleteToken}
|
||||
deletionButtonI18nKey={'common.delete'}
|
||||
<CommonModal
|
||||
show={showDeleteModal}
|
||||
onHide={() => setShowDeleteModal(false)}
|
||||
titleI18nKey={'profile.modal.deleteAccessToken.title'}>
|
||||
<Trans i18nKey='profile.modal.deleteAccessToken.message' />
|
||||
</DeletionModal>
|
||||
titleI18nKey={'profile.modal.deleteAccessToken.title'}
|
||||
{...cypressId('access-token-modal-delete')}>
|
||||
<Modal.Body>
|
||||
<Trans i18nKey='profile.modal.deleteAccessToken.message' />
|
||||
</Modal.Body>
|
||||
<Modal.Footer>
|
||||
<Button variant='danger' onClick={deleteToken}>
|
||||
<Trans i18nKey={'common.delete'} />
|
||||
</Button>
|
||||
</Modal.Footer>
|
||||
</CommonModal>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue