Merge pull request #30908 from overleaf/mj-remove-opt-out

[web] Tear down editor-redesign-opt-out

GitOrigin-RevId: c826691f3fdd4ad31403abae8adb353bd8c34897
This commit is contained in:
Mathias Jakobsen
2026-01-26 11:27:22 +00:00
committed by Copybot
parent b517df6672
commit 9223515705
22 changed files with 166 additions and 303 deletions

View File

@@ -461,7 +461,6 @@ const _ProjectController = {
'writefull-encourage-prompt-for-paraphrase',
'editor-context-menu',
'email-notifications',
'editor-redesign-no-opt-out',
].filter(Boolean)
const getUserValues = async userId =>

View File

@@ -1194,7 +1194,6 @@
"not_a_student": "",
"not_managed": "",
"not_now": "",
"not_sure_about_switching_yet": "",
"notification": "",
"notification_personal_and_group_subscriptions": "",
"notification_project_invite_accepted_message": "",
@@ -1430,7 +1429,6 @@
"reactivating": "",
"read_lines_from_path": "",
"read_more": "",
"read_more_about_the_new_editor": "",
"read_more_about_the_new_editor_or_explore_our_documentation_for_tips_and_tricks": "",
"read_only_dropbox_sync_message": "",
"read_only_token": "",
@@ -1661,7 +1659,6 @@
"setup_another_account_under_a_personal_email_address": "",
"share": "",
"share_feedback": "",
"share_feedback_on_the_new_editor": "",
"share_project": "",
"shared_with_you": "",
"sharelatex_beta_program": "",
@@ -1892,7 +1889,6 @@
"the_home_of_research_writing": "",
"the_latex_engine_used_for_compiling": "",
"the_new_and_improved_overleaf_editor_design": "",
"the_new_overleaf_editor_info": "",
"the_next_payment_will_be_collected_on": "",
"the_original_text_has_changed": "",
"the_overleaf_color_scheme": "",

View File

@@ -0,0 +1,38 @@
import { Trans, useTranslation } from 'react-i18next'
import EditorTourTooltip from './editor-tour-tooltip'
export default function EditorTourGotQuestionsTooltip({
target,
}: {
target: HTMLElement | null
}) {
const { t } = useTranslation()
return (
<EditorTourTooltip
target={target}
placement="right-end"
stage="got-questions"
header={t('got_questions')}
>
<Trans
i18nKey="read_more_about_the_new_editor_or_explore_our_documentation_for_tips_and_tricks"
components={[
/* eslint-disable-next-line jsx-a11y/anchor-has-content, react/jsx-key */
<a
href="https://www.overleaf.com/blog/introducing-overleafs-new-look"
target="_blank"
rel="noopener noreferrer"
key="link"
/>,
/* eslint-disable-next-line jsx-a11y/anchor-has-content, react/jsx-key */
<a
href="https://docs.overleaf.com/getting-started/how-do-i-use-overleaf/redesigned-overleaf-editor"
target="_blank"
rel="noopener noreferrer"
key="link"
/>,
]}
/>
</EditorTourTooltip>
)
}

View File

@@ -1,63 +0,0 @@
import { Trans, useTranslation } from 'react-i18next'
import EditorTourTooltip from './editor-tour-tooltip'
import { useFeatureFlag } from '@/shared/context/split-test-context'
export default function EditorTourSwitchBackTooltip({
target,
}: {
target: HTMLElement | null
}) {
const { t } = useTranslation()
// NOTE: This should really be a different component, but to reduce
// complexity of the tour code, let's just change the content here.
// The feature flag can be torn down soon, and the component renamed.
const noOptOut = useFeatureFlag('editor-redesign-no-opt-out')
const canSwitchBack = !noOptOut
return (
<EditorTourTooltip
target={target}
placement="right-end"
stage="switch-back"
header={
canSwitchBack ? t('not_sure_about_switching_yet') : t('got_questions')
}
>
{canSwitchBack ? (
<Trans
i18nKey="read_more_about_the_new_editor"
components={[
/* eslint-disable-next-line jsx-a11y/anchor-has-content, react/jsx-key */
<a
href="https://www.overleaf.com/blog/introducing-overleafs-new-look"
target="_blank"
rel="noopener noreferrer"
key="link"
/>,
<strong key="strong" />,
]}
/>
) : (
<Trans
i18nKey="read_more_about_the_new_editor_or_explore_our_documentation_for_tips_and_tricks"
components={[
/* eslint-disable-next-line jsx-a11y/anchor-has-content, react/jsx-key */
<a
href="https://www.overleaf.com/blog/introducing-overleafs-new-look"
target="_blank"
rel="noopener noreferrer"
key="link"
/>,
/* eslint-disable-next-line jsx-a11y/anchor-has-content, react/jsx-key */
<a
href="https://docs.overleaf.com/getting-started/how-do-i-use-overleaf/redesigned-overleaf-editor"
target="_blank"
rel="noopener noreferrer"
key="link"
/>,
]}
/>
)}
</EditorTourTooltip>
)
}

View File

@@ -6,6 +6,7 @@ import {
ElementType,
useCallback,
KeyboardEventHandler,
useMemo,
} from 'react'
import { useTranslation } from 'react-i18next'
import OLTooltip from '@/shared/components/ol/ol-tooltip'
@@ -106,7 +107,10 @@ function LogEntryHeader({
) : null
const headerTitleText = logType ? `${logType} ${headerTitle}` : headerTitle
const fileData = file && findEntityByPath(file)
const fileData = useMemo(
() => file && findEntityByPath(file),
[file, findEntityByPath]
)
const showGoToCodeButton =
showSourceLocationLink &&
!!fileData &&

View File

@@ -29,7 +29,7 @@ import useRailOverflow from '../../hooks/use-rail-overflow'
import EditorTourRailTooltip from '../editor-tour/editor-tour-rail-tooltip'
import importOverleafModules from '../../../../../macros/import-overleaf-module.macro'
import EditorTourThemeTooltip from '../editor-tour/editor-tour-theme-tooltip'
import EditorTourSwitchBackTooltip from '../editor-tour/editor-tour-switch-back-tooltip'
import EditorTourGotQuestionsTooltip from '../editor-tour/editor-tour-got-questions'
import { shouldIncludeElement } from '../../utils/rail-utils'
import { useEditorContext } from '@/shared/context/editor-context'
@@ -280,7 +280,7 @@ export const RailLayout = () => {
</nav>
<EditorTourRailTooltip target={fileTreeRef.current} />
<EditorTourThemeTooltip target={settingsRef.current} />
<EditorTourSwitchBackTooltip target={settingsRef.current} />
<EditorTourGotQuestionsTooltip target={settingsRef.current} />
{moduleRailPopovers
.filter(shouldIncludeElement)
.map(({ key, Component, ref }) => (

View File

@@ -1,45 +0,0 @@
import ToggleSetting from '../toggle-setting'
import { useTranslation } from 'react-i18next'
import { useSwitchEnableNewEditorState } from '@/features/ide-redesign/hooks/use-switch-enable-new-editor-state'
import { useIsNewEditorEnabled } from '@/features/ide-redesign/utils/new-editor-utils'
import { useCallback } from 'react'
import { useLayoutContext } from '@/shared/context/layout-context'
import { useEditorAnalytics } from '@/shared/hooks/use-editor-analytics'
import getMeta from '@/utils/meta'
export default function NewEditorSetting() {
const { isOverleaf } = getMeta('ol-ExposedSettings')
const { t } = useTranslation()
const { setEditorRedesignStatus } = useSwitchEnableNewEditorState()
const { setLeftMenuShown } = useLayoutContext()
const enabled = useIsNewEditorEnabled()
const { sendEvent } = useEditorAnalytics()
const handleToggle = useCallback(() => {
sendEvent('switch-to-old-editor', { location: 'settings-modal' })
setEditorRedesignStatus(!enabled).then(() => setLeftMenuShown(false))
}, [enabled, setEditorRedesignStatus, setLeftMenuShown, sendEvent])
return (
<ToggleSetting
id="new-editor-setting"
label={t('new_editor_look')}
description={
<>
<div>{t('the_new_overleaf_editor_info')}</div>
{isOverleaf && (
<a
href="https://forms.gle/3tPYhXcBVGmUB2HXA"
target="_blank"
rel="noopener noreferrer"
>
{t('share_feedback_on_the_new_editor')}
</a>
)}
</>
}
checked={enabled}
onChange={handleToggle}
/>
)
}

View File

@@ -8,7 +8,7 @@ import {
useState,
} from 'react'
export type NewEditorTourStage = 'rail' | 'logs' | 'theme' | 'switch-back'
export type NewEditorTourStage = 'rail' | 'logs' | 'theme' | 'got-questions'
const NewEditorTourContext = createContext<
| {
@@ -25,11 +25,11 @@ const NewEditorTourContext = createContext<
| undefined
>(undefined)
const STAGES: NewEditorTourStage[] = ['rail', 'logs', 'theme', 'switch-back']
const STAGES: NewEditorTourStage[] = ['rail', 'logs', 'theme', 'got-questions']
const EDITOR_ONLY_STAGES: NewEditorTourStage[] = [
'rail',
'theme',
'switch-back',
'got-questions',
]
export const NewEditorTourProvider: FC<React.PropsWithChildren> = ({

View File

@@ -24,7 +24,6 @@ import LineHeightSetting from '../components/settings/appearance-settings/line-h
import FontFamilySetting from '../components/settings/appearance-settings/font-family-setting'
import { AvailableUnfilledIcon } from '@/shared/components/material-icon'
import { EditorLeftMenuProvider } from '@/features/editor-left-menu/components/editor-left-menu-context'
import NewEditorSetting from '../components/settings/editor-settings/new-editor-setting'
import DarkModePdfSetting from '../components/settings/appearance-settings/dark-mode-pdf-setting'
import { useProjectSettingsContext } from '@/features/editor-left-menu/context/project-settings-context'
import { useFeatureFlag } from '@/shared/context/split-test-context'
@@ -88,7 +87,6 @@ export const SettingsModalProvider: FC<React.PropsWithChildren> = ({
const { leftMenuShown, setLeftMenuShown } = useLayoutContext()
const hasEmailNotifications = useFeatureFlag('email-notifications')
const noNewEditorOptOut = useFeatureFlag('editor-redesign-no-opt-out')
const allSettingsTabs: SettingsEntry[] = useMemo(
() => [
@@ -226,11 +224,6 @@ export const SettingsModalProvider: FC<React.PropsWithChildren> = ({
key: 'lineHeight',
component: <LineHeightSetting />,
},
{
key: 'newEditor',
component: <NewEditorSetting />,
hidden: noNewEditorOptOut,
},
],
},
],
@@ -267,7 +260,7 @@ export const SettingsModalProvider: FC<React.PropsWithChildren> = ({
href: '/user/subscription',
},
],
[t, overallTheme, hasEmailNotifications, noNewEditorOptOut]
[t, overallTheme, hasEmailNotifications]
)
const settingsTabs = useMemo(

View File

@@ -1,4 +1,3 @@
import { useFeatureFlag } from '@/shared/context/split-test-context'
import { useUserSettingsContext } from '@/shared/context/user-settings-context'
// For e2e tests purposes, allow overriding to old editor
@@ -11,17 +10,7 @@ export const canUseNewEditor = () => {
}
export const useIsNewEditorEnabled = () => {
const { userSettings } = useUserSettingsContext()
const noOptOut = useFeatureFlag('editor-redesign-no-opt-out')
const hasAccess = canUseNewEditor()
if (!hasAccess) {
return false
}
const enabled = userSettings.enableNewEditor
if (noOptOut) {
return true
}
return enabled
return canUseNewEditor()
}
export const useIsNewToNewEditor = () => {

View File

@@ -1540,7 +1540,6 @@
"not_managed": "Not managed",
"not_now": "Not now",
"not_registered": "Not registered",
"not_sure_about_switching_yet": "Not sure about switching yet?",
"note_features_under_development": "<0>Please note</0> that features in this program are still being tested and actively developed. This means that they might <0>change</0>, be <0>removed</0> or <0>become part of a premium plan</0>",
"notification": "Notification",
"notification_features_upgraded_by_affiliation": "Good news! Your affiliated organization __institutionName__ has an Overleaf subscription, and you now have access to all of Overleafs Professional features.",
@@ -1847,7 +1846,6 @@
"reactivating": "Reactivating",
"read_lines_from_path": "Read lines from __path__",
"read_more": "Read more",
"read_more_about_the_new_editor": "<0>Read more about the new editor design</0>, or temporarily switch back to the old editor using the <1>Appearance</1> settings.",
"read_more_about_the_new_editor_or_explore_our_documentation_for_tips_and_tricks": "<0>Read more</0> about the new editor, or <1>explore our documentation</1> for tips and tricks.",
"read_only_dropbox_sync_message": "As a read-only viewer you can sync the current project version to Dropbox, but changes made in Dropbox will <0>not</0> sync back to Overleaf.",
"read_only_token": "Read-Only Token",
@@ -2132,7 +2130,6 @@
"setup_another_account_under_a_personal_email_address": "Set up another Overleaf account under a personal email address.",
"share": "Share",
"share_feedback": "Share feedback",
"share_feedback_on_the_new_editor": "Share feedback on the new editor look.",
"share_project": "Share Project",
"shared_with_you": "Shared with you",
"sharelatex_beta_program": "__appName__ beta program",
@@ -2408,7 +2405,6 @@
"the_home_of_research_writing": "The home of research writing.",
"the_latex_engine_used_for_compiling": "The LaTeX engine used for compiling",
"the_new_and_improved_overleaf_editor_design": "The new and improved __appName__ editor design brings you a cleaner, less cluttered interface to help you focus on what matters—your work.",
"the_new_overleaf_editor_info": "__appName__s new look is here. Disabling this option will switch you back to the old editor design.",
"the_next_payment_will_be_collected_on": "The next payment will be collected on <strong>__date__</strong>.",
"the_original_text_has_changed": "The original text has changed, so this suggestion cant be applied",
"the_overleaf_color_scheme": "The __appName__ color scheme",

View File

@@ -3,7 +3,7 @@ import PdfLogsEntries from '../../../../frontend/js/features/pdf-preview/compone
import { detachChannel, testDetachChannel } from '../../helpers/detach-channel'
import { FileTreePathContext } from '@/features/file-tree/contexts/file-tree-path'
import { FindResult } from '@/features/file-tree/util/path'
import { FC } from 'react'
import { FC, ReactElement } from 'react'
import {
EditorManager,
EditorManagerContext,
@@ -62,6 +62,14 @@ describe('<PdfLogsEntries/>', function () {
)
}
// TODO: ide-redesign-cleanup: Remove this wrapper when the styles are no
// longer nested in .ide-redesign-main .error-logs
const LogsPanel = ({ children }: { children: ReactElement }) => (
<div className="ide-redesign-main">
<div className="error-logs"> {children}</div>
</div>
)
const logEntries: LogEntry[] = [
{
file: 'main.tex',
@@ -84,7 +92,9 @@ describe('<PdfLogsEntries/>', function () {
it('displays human readable hint', function () {
cy.mount(
<EditorProviders providers={{ EditorViewProvider }}>
<PdfLogsEntries entries={logEntries} />
<LogsPanel>
<PdfLogsEntries entries={logEntries} />
</LogsPanel>
</EditorProviders>
)
@@ -100,15 +110,17 @@ describe('<PdfLogsEntries/>', function () {
EditorViewProvider,
}}
>
<PdfLogsEntries entries={logEntries} />
<LogsPanel>
<PdfLogsEntries entries={logEntries} />
</LogsPanel>
</EditorProviders>
)
cy.findByRole('button', {
name: 'Navigate to log position in source code: main.tex, 9',
name: 'Go to code location',
}).click()
cy.get('@findEntityByPath').should('have.been.calledOnceWith', 'main.tex')
cy.get('@findEntityByPath').should('have.been.calledWith', 'main.tex')
cy.get('@openDocWithId').should(
'have.been.calledOnceWith',
fakeFindEntityResult.entity._id,
@@ -133,7 +145,9 @@ describe('<PdfLogsEntries/>', function () {
EditorViewProvider,
}}
>
<PdfLogsEntries entries={logEntries} />
<LogsPanel>
<PdfLogsEntries entries={logEntries} />
</LogsPanel>
</EditorProviders>
).then(() => {
testDetachChannel.postMessage({
@@ -151,7 +165,7 @@ describe('<PdfLogsEntries/>', function () {
})
})
cy.get('@findEntityByPath').should('have.been.calledOnce')
cy.get('@findEntityByPath').should('have.been.called')
cy.get('@openDocWithId').should(
'have.been.calledOnceWith',
fakeFindEntityResult.entity._id,
@@ -176,17 +190,18 @@ describe('<PdfLogsEntries/>', function () {
EditorViewProvider,
}}
>
<PdfLogsEntries entries={logEntries} />
<LogsPanel>
<PdfLogsEntries entries={logEntries} />
</LogsPanel>
</EditorProviders>
)
cy.spy(detachChannel, 'postMessage').as('postDetachMessage')
cy.findByRole('button', {
name: 'Navigate to log position in source code: main.tex, 9',
name: 'Go to code location',
}).click()
cy.get('@findEntityByPath').should('not.have.been.called')
cy.get('@openDocWithId').should('not.have.been.called')
cy.get('@postDetachMessage').should('have.been.calledWith', {
role: 'detached',

View File

@@ -7,7 +7,7 @@ import {
IdeView,
useLayoutContext,
} from '../../../../frontend/js/shared/context/layout-context'
import { FC, PropsWithChildren, useEffect } from 'react'
import { FC, PropsWithChildren, ReactElement, useEffect } from 'react'
import { useLocalCompileContext } from '@/shared/context/local-compile-context'
import { ProjectCompiler } from '../../../../types/project-settings'
@@ -29,6 +29,16 @@ const Layout: FC<{ layout: IdeLayout; view?: IdeView }> = ({
return null
}
const PdfViewer = ({ children }: { children: ReactElement }) => {
return (
// TODO: ide-redesign-cleanup: Remove the .ide-redesign-main wrapper when
// the styles are no longer nested in that.
<div className="ide-redesign-main">
<div className="pdf-viewer">{children}</div>
</div>
)
}
describe('<PdfPreview/>', function () {
let projectId: string
beforeEach(function () {
@@ -63,9 +73,9 @@ describe('<PdfPreview/>', function () {
cy.mount(
<EditorProviders scope={scope}>
<div className="pdf-viewer">
<PdfViewer>
<PdfPreview />
</div>
</PdfViewer>
</EditorProviders>
)
@@ -87,9 +97,9 @@ describe('<PdfPreview/>', function () {
cy.mount(
<EditorProviders scope={scope}>
<div className="pdf-viewer">
<PdfViewer>
<PdfPreview />
</div>
</PdfViewer>
</EditorProviders>
)
@@ -111,9 +121,9 @@ describe('<PdfPreview/>', function () {
cy.mount(
<EditorProviders scope={scope}>
<div className="pdf-viewer">
<PdfViewer>
<PdfPreview />
</div>
</PdfViewer>
</EditorProviders>
)
@@ -162,9 +172,9 @@ describe('<PdfPreview/>', function () {
const scope = mockScope()
cy.mount(
<EditorProviders scope={scope} projectId={projectId}>
<div className="pdf-viewer">
<PdfViewer>
<PdfPreview />
</div>
</PdfViewer>
</EditorProviders>
)
@@ -272,9 +282,9 @@ describe('<PdfPreview/>', function () {
cy.mount(
<EditorProviders scope={scope} projectId={projectId} {...props}>
<div className="pdf-viewer">
<PdfViewer>
<PdfPreview />
</div>
</PdfViewer>
</EditorProviders>
)
@@ -292,9 +302,9 @@ describe('<PdfPreview/>', function () {
cy.mount(
<EditorProviders scope={scope}>
<div className="pdf-viewer">
<PdfViewer>
<PdfPreview />
</div>
</PdfViewer>
</EditorProviders>
)
@@ -314,9 +324,9 @@ describe('<PdfPreview/>', function () {
cy.mount(
<EditorProviders scope={scope}>
<div className="pdf-viewer">
<PdfViewer>
<PdfPreview />
</div>
</PdfViewer>
</EditorProviders>
)
@@ -338,9 +348,9 @@ describe('<PdfPreview/>', function () {
cy.mount(
<EditorProviders scope={scope}>
<div className="pdf-viewer">
<PdfViewer>
<PdfPreview />
</div>
</PdfViewer>
</EditorProviders>
)
@@ -372,9 +382,9 @@ describe('<PdfPreview/>', function () {
cy.mount(
<EditorProviders scope={scope}>
<div className="pdf-viewer">
<PdfViewer>
<PdfPreview />
</div>
</PdfViewer>
</EditorProviders>
)
@@ -395,9 +405,9 @@ describe('<PdfPreview/>', function () {
cy.mount(
<EditorProviders scope={scope}>
<div className="pdf-viewer">
<PdfViewer>
<PdfPreview />
</div>
</PdfViewer>
</EditorProviders>
)
@@ -429,9 +439,9 @@ describe('<PdfPreview/>', function () {
cy.mount(
<EditorProviders scope={scope}>
<div className="pdf-viewer">
<PdfViewer>
<PdfPreview />
</div>
</PdfViewer>
</EditorProviders>
)
@@ -470,9 +480,9 @@ describe('<PdfPreview/>', function () {
cy.mount(
<EditorProviders scope={scope} userSettings={userSettings}>
<WithLintingErrors>
<div className="pdf-viewer">
<PdfViewer>
<PdfPreview />
</div>
</PdfViewer>
</WithLintingErrors>
</EditorProviders>
)
@@ -498,7 +508,9 @@ describe('<PdfPreview/>', function () {
// NOTE: difficult to assert that a request hasn't been sent
cy.findByRole('button', { name: 'Recompile' })
cy.findByText('Code check failed')
cy.findByText(
'Your code has errors that need to be fixed before the auto-compile can run'
)
})
it('does not run a compile on doc change if the PDF preview is not open', function () {
@@ -509,9 +521,9 @@ describe('<PdfPreview/>', function () {
cy.mount(
<EditorProviders scope={scope}>
<Layout layout="flat" view="editor" />
<div className="pdf-viewer">
<PdfViewer>
<PdfPreview />
</div>
</PdfViewer>
</EditorProviders>
)
@@ -570,9 +582,9 @@ describe('<PdfPreview/>', function () {
cy.mount(
<EditorProviders scope={scope}>
<div className="pdf-viewer">
<PdfViewer>
<PdfPreview />
</div>
</PdfViewer>
</EditorProviders>
)
@@ -590,9 +602,9 @@ describe('<PdfPreview/>', function () {
cy.mount(
<EditorProviders scope={scope}>
<div className="pdf-viewer">
<PdfViewer>
<PdfPreview />
</div>
</PdfViewer>
</EditorProviders>
)
@@ -601,9 +613,10 @@ describe('<PdfPreview/>', function () {
cy.findByRole('button', { name: 'View logs' }).click()
cy.findByRole('button', { name: 'View PDF' })
cy.findByRole('button', { name: 'Expand' }).click()
cy.findByRole('button', { name: 'Collapse' }).click()
cy.findByLabelText('Raw logs from the LaTeX compiler').within(() => {
cy.findByRole('button', { name: 'Expand' }).click()
cy.findByRole('button', { name: 'Collapse' }).click()
})
})
it('displays error messages if there were validation problems', function () {
@@ -638,9 +651,9 @@ describe('<PdfPreview/>', function () {
cy.mount(
<EditorProviders scope={scope}>
<div className="pdf-viewer">
<PdfViewer>
<PdfPreview />
</div>
</PdfViewer>
</EditorProviders>
)
@@ -660,9 +673,9 @@ describe('<PdfPreview/>', function () {
cy.mount(
<EditorProviders scope={scope}>
<div className="pdf-viewer">
<PdfViewer>
<PdfPreview />
</div>
</PdfViewer>
</EditorProviders>
)
@@ -705,9 +718,9 @@ describe('<PdfPreview/>', function () {
cy.mount(
<EditorProviders scope={scope}>
<div className="pdf-viewer">
<PdfViewer>
<PdfPreview />
</div>
</PdfViewer>
</EditorProviders>
)
@@ -768,9 +781,9 @@ describe('<PdfPreview/>', function () {
cy.mount(
<EditorProviders scope={scope}>
<div className="pdf-viewer">
<PdfViewer>
<PdfPreview />
</div>
</PdfViewer>
</EditorProviders>
)
@@ -796,9 +809,9 @@ describe('<PdfPreview/>', function () {
cy.mount(
<EditorProviders scope={scope}>
<div className="pdf-viewer">
<PdfViewer>
<PdfPreview />
</div>
</PdfViewer>
</EditorProviders>
)
@@ -826,9 +839,9 @@ describe('<PdfPreview/>', function () {
cy.mount(
<EditorProviders scope={scope}>
<div className="pdf-viewer">
<PdfViewer>
<PdfPreview />
</div>
</PdfViewer>
</EditorProviders>
)
@@ -859,9 +872,9 @@ describe('<PdfPreview/>', function () {
cy.mount(
<EditorProviders scope={scope}>
<div className="pdf-viewer">
<PdfViewer>
<PdfPreview />
</div>
</PdfViewer>
</EditorProviders>
)

View File

@@ -224,6 +224,7 @@ describe('<LayoutDropdownButton />', function () {
layout: 'flat',
view: 'editor',
page: '/detacher',
'editor-redesign': 'enabled',
})
})

View File

@@ -19,12 +19,11 @@ describe('<FileTreeFolder/>', function () {
</FileTreeProvider>
</EditorProviders>
)
cy.findByRole('treeitem', { selected: false })
cy.findByRole('tree').should('not.exist')
})
it('renders selected', function () {
it('expands when selected', function () {
const rootFolder = [
{
_id: 'root-folder-id',
@@ -51,7 +50,7 @@ describe('<FileTreeFolder/>', function () {
cy.findByRole('treeitem', { selected: false }).click()
cy.findByRole('treeitem', { selected: true })
cy.findByRole('tree').should('not.exist')
cy.findByRole('tree').should('exist')
})
it('expands', function () {
@@ -80,7 +79,7 @@ describe('<FileTreeFolder/>', function () {
)
cy.findByRole('treeitem')
cy.findByRole('button', { name: 'Expand' }).click()
cy.findByLabelText('Expand').click()
cy.findByRole('tree')
})
@@ -110,7 +109,7 @@ describe('<FileTreeFolder/>', function () {
)
cy.findByRole('tree').should('not.exist')
cy.findByRole('button', { name: 'Expand' }).click()
cy.findByLabelText('Expand').click()
cy.findByRole('tree')
cy.then(() => ReactDom.unmountComponentAtNode(getContainerEl()))

View File

@@ -66,7 +66,7 @@ describe('<FileTreeitemInner />', function () {
cy.findByRole('menu')
// close the context menu
cy.get('div.entity').click()
cy.get('div.entity').click({ force: true })
cy.findByRole('menu').should('not.exist')
})
})
@@ -86,7 +86,8 @@ describe('<FileTreeitemInner />', function () {
</EditorProviders>
)
cy.findByRole('button', { name: 'bar.tex' })
// TODO: ide-redesign-cleanup: Can we add a better selector here?
cy.findByText('bar.tex')
cy.findByRole('textbox').should('not.exist')
})
@@ -117,7 +118,7 @@ describe('<FileTreeitemInner />', function () {
cy.findByRole('button', { name: 'Open bar.tex action menu' }).click()
cy.findByRole('menuitem', { name: 'Rename' }).click()
cy.findByRole('button', { name: 'bar.tex' }).should('not.exist')
cy.findByRole('treeitem', { name: 'bar.tex' }).should('not.exist')
cy.findByRole('textbox')
})
})

View File

@@ -3,7 +3,7 @@ import { EditorProviders } from '../../../../helpers/editor-providers'
import { FileTreeProvider } from '../../helpers/file-tree-provider'
describe('<FileTreeItemName />', function () {
it('renders name as button', function () {
it('renders name', function () {
cy.mount(
<EditorProviders>
<FileTreeProvider>
@@ -16,93 +16,22 @@ describe('<FileTreeItemName />', function () {
</EditorProviders>
)
cy.findByRole('button', { name: 'foo.tex' })
cy.findByRole('textbox').should('not.exist')
cy.findByText('foo.tex')
})
it("doesn't start renaming on unselected component", function () {
cy.mount(
<EditorProviders>
<FileTreeProvider>
<FileTreeItemName
name="foo.tex"
isSelected={false}
setIsDraggable={cy.stub()}
/>
</FileTreeProvider>
</EditorProviders>
)
cy.findByRole('button').click()
cy.findByRole('button').click()
cy.findByRole('button').dblclick()
cy.findByRole('textbox').should('not.exist')
})
it('start renaming on double-click', function () {
it('does not render name as a button', function () {
cy.mount(
<EditorProviders>
<FileTreeProvider>
<FileTreeItemName
name="foo.tex"
isSelected
setIsDraggable={cy.stub().as('setIsDraggable')}
setIsDraggable={cy.stub()}
/>
</FileTreeProvider>
</EditorProviders>
)
cy.findByRole('button').click()
cy.findByRole('button').click()
cy.findByRole('button').dblclick()
cy.findByRole('textbox')
cy.findByRole('button').should('not.exist')
cy.get('@setIsDraggable').should('have.been.calledWith', false)
})
it('cannot start renaming in read-only', function () {
cy.mount(
<EditorProviders permissionsLevel="readOnly">
<FileTreeProvider>
<FileTreeItemName
name="foo.tex"
isSelected
setIsDraggable={cy.stub()}
/>
</FileTreeProvider>
</EditorProviders>
)
cy.findByRole('button').click()
cy.findByRole('button').click()
cy.findByRole('button').dblclick()
cy.findByRole('textbox').should('not.exist')
})
describe('stop renaming', function () {
it('on Escape', function () {
cy.mount(
<EditorProviders>
<FileTreeProvider>
<FileTreeItemName
name="foo.tex"
isSelected
setIsDraggable={cy.stub().as('setIsDraggable')}
/>
</FileTreeProvider>
</EditorProviders>
)
cy.findByRole('button').click()
cy.findByRole('button').click()
cy.findByRole('button').dblclick()
cy.findByRole('textbox').clear()
cy.findByRole('textbox').type('bar.tex{esc}')
cy.findByRole('button', { name: 'foo.tex' })
cy.get('@setIsDraggable').should('have.been.calledWith', true)
})
})
})

View File

@@ -37,7 +37,7 @@ describe('FileTree Context Menu Flow', function () {
)
cy.findByRole('menu').should('not.exist')
cy.findByRole('button', { name: 'main.tex' }).trigger('contextmenu')
cy.findByRole('treeitem', { name: 'main.tex' }).trigger('contextmenu')
cy.findByRole('menu')
})
@@ -73,9 +73,9 @@ describe('FileTree Context Menu Flow', function () {
)
cy.findByRole('menu').should('not.exist')
cy.findByRole('button', { name: 'main.tex' }).trigger('contextmenu')
cy.findByRole('treeitem', { name: 'main.tex' }).trigger('contextmenu')
cy.findByRole('menu')
cy.findAllByRole('button', { name: 'foo.tex' }).click()
cy.findAllByRole('treeitem', { name: 'foo.tex' }).click()
cy.findByRole('menu').should('not.exist')
})
@@ -108,7 +108,7 @@ describe('FileTree Context Menu Flow', function () {
</EditorProviders>
)
cy.findAllByRole('button', { name: 'main.tex' }).trigger('contextmenu')
cy.findAllByRole('treeitem', { name: 'main.tex' }).trigger('contextmenu')
cy.findByRole('menu').should('not.exist')
})
@@ -146,14 +146,14 @@ describe('FileTree Context Menu Flow', function () {
cy.findByRole('menu').should('not.exist')
// main.tex is already the main document
cy.findByRole('button', { name: 'main.tex' }).trigger('contextmenu')
cy.findByRole('treeitem', { name: 'main.tex' }).trigger('contextmenu')
cy.findByRole('menu')
.findByRole('menuitem', { name: 'Set as main document' })
.should('not.exist')
// set other.tex as the main document
cy.findByRole('button', { name: 'other.tex' }).click({ force: true })
cy.findByRole('button', { name: 'other.tex' }).trigger('contextmenu')
cy.findByRole('treeitem', { name: 'other.tex' }).click({ force: true })
cy.findByRole('treeitem', { name: 'other.tex' }).trigger('contextmenu')
cy.intercept('POST', '/project/123abc/settings', { statusCode: 204 }).as(
'update-settings'
@@ -168,7 +168,7 @@ describe('FileTree Context Menu Flow', function () {
.should('eq', 'other-doc')
// main.tex is now not the main document
cy.findByRole('button', { name: 'main.tex' }).trigger('contextmenu')
cy.findByRole('treeitem', { name: 'main.tex' }).trigger('contextmenu')
cy.findByRole('menu').findByRole('menuitem', {
name: 'Set as main document',
})

View File

@@ -109,7 +109,7 @@ describe('FileTree Create Folder Flow', function () {
</EditorProviders>
)
cy.findByRole('button', { name: 'Expand' }).click()
cy.findByLabelText('Expand').click()
const name = 'Foo Bar In thefolder'
@@ -144,7 +144,7 @@ describe('FileTree Create Folder Flow', function () {
cy.findByRole('treeitem', { name })
// collapse the parent folder; created folder should not be rendered anymore
cy.findByRole('button', { name: 'Collapse' }).click()
cy.findByLabelText('Collapse').click()
cy.findByRole('treeitem', { name }).should('not.exist')
})
@@ -218,7 +218,7 @@ describe('FileTree Create Folder Flow', function () {
cy.findByRole('treeitem', { name })
// collapse the parent folder; created folder should not be rendered anymore
cy.findByRole('button', { name: 'Collapse' }).click()
cy.findByLabelText('Collapse').click()
cy.findByRole('treeitem', { name }).should('not.exist')
})

View File

@@ -177,7 +177,7 @@ describe('FileTree Delete Entity Flow', function () {
</div>
)
cy.findByRole('button', { name: 'Expand' }).click()
cy.findByLabelText('Expand').click()
cy.findByRole('treeitem', { name: 'main.tex' }).click()
cy.findByRole('treeitem', { name: 'my.bib' }).click({
ctrlKey: true,
@@ -248,7 +248,7 @@ describe('FileTree Delete Entity Flow', function () {
})
// open the context menu
cy.findByRole('button', { name: 'my.bib' }).trigger('contextmenu')
cy.findByRole('treeitem', { name: 'my.bib' }).trigger('contextmenu')
// make sure the menu has opened, with only a "Delete" item (as multiple files are selected)
cy.findByRole('menu')

View File

@@ -85,7 +85,7 @@ describe('FileTree Rename Entity Flow', function () {
'renameFile'
)
cy.findByRole('button', { name: 'Expand' }).click()
cy.findByLabelText('Expand').click()
renameItem('c.tex', 'd.tex')
@@ -122,7 +122,7 @@ describe('FileTree Rename Entity Flow', function () {
})
it('shows error modal on duplicate filename in subfolder', function () {
cy.findByRole('button', { name: 'Expand' }).click()
cy.findByLabelText('Expand').click()
renameItem('c.tex', 'e.tex')

View File

@@ -274,9 +274,7 @@ describe('<ReviewPanel />', function () {
describe('toggler', function () {
it('should close panel when pressing close button', function () {
cy.get('@review-panel').within(() => {
cy.findByLabelText('Close').click({ scrollBehavior: false })
})
cy.findByLabelText('Close').click({ scrollBehavior: false })
// We should collapse to the mini state
cy.get('.review-panel-mini').should('exist')
})