Просмотр исходного кода

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

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

GitOrigin-RevId: c826691f3fdd4ad31403abae8adb353bd8c34897
Mathias Jakobsen 6 месяцев назад
Родитель
Сommit
9223515705
22 измененных файлов с 166 добавлено и 303 удалено
  1. 0 1
      services/web/app/src/Features/Project/ProjectController.mjs
  2. 0 4
      services/web/frontend/extracted-translations.json
  3. 38 0
      services/web/frontend/js/features/ide-redesign/components/editor-tour/editor-tour-got-questions.tsx
  4. 0 63
      services/web/frontend/js/features/ide-redesign/components/editor-tour/editor-tour-switch-back-tooltip.tsx
  5. 5 1
      services/web/frontend/js/features/ide-redesign/components/error-logs/log-entry-header.tsx
  6. 2 2
      services/web/frontend/js/features/ide-redesign/components/rail/rail.tsx
  7. 0 45
      services/web/frontend/js/features/ide-redesign/components/settings/editor-settings/new-editor-setting.tsx
  8. 3 3
      services/web/frontend/js/features/ide-redesign/contexts/new-editor-tour-context.tsx
  9. 1 8
      services/web/frontend/js/features/ide-redesign/contexts/settings-modal-context.tsx
  10. 1 12
      services/web/frontend/js/features/ide-redesign/utils/new-editor-utils.ts
  11. 0 4
      services/web/locales/en.json
  12. 25 10
      services/web/test/frontend/components/pdf-preview/pdf-logs-entries.spec.tsx
  13. 62 49
      services/web/test/frontend/components/pdf-preview/pdf-preview.spec.tsx
  14. 1 0
      services/web/test/frontend/features/editor-navigation-toolbar/components/layout-dropdown-button.test.tsx
  15. 4 5
      services/web/test/frontend/features/file-tree/components/file-tree-folder.spec.tsx
  16. 4 3
      services/web/test/frontend/features/file-tree/components/file-tree-item/file-tree-item-inner.spec.tsx
  17. 4 75
      services/web/test/frontend/features/file-tree/components/file-tree-item/file-tree-item-name.spec.tsx
  18. 8 8
      services/web/test/frontend/features/file-tree/flows/context-menu.spec.tsx
  19. 3 3
      services/web/test/frontend/features/file-tree/flows/create-folder.spec.tsx
  20. 2 2
      services/web/test/frontend/features/file-tree/flows/delete-entity.spec.tsx
  21. 2 2
      services/web/test/frontend/features/file-tree/flows/rename-entity.spec.tsx
  22. 1 3
      services/web/test/frontend/features/review-panel/review-panel.spec.tsx

+ 0 - 1
services/web/app/src/Features/Project/ProjectController.mjs

@@ -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 =>

+ 0 - 4
services/web/frontend/extracted-translations.json

@@ -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": "",

+ 38 - 0
services/web/frontend/js/features/ide-redesign/components/editor-tour/editor-tour-got-questions.tsx

@@ -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>
+  )
+}

+ 0 - 63
services/web/frontend/js/features/ide-redesign/components/editor-tour/editor-tour-switch-back-tooltip.tsx

@@ -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>
-  )
-}

+ 5 - 1
services/web/frontend/js/features/ide-redesign/components/error-logs/log-entry-header.tsx

@@ -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 &&

+ 2 - 2
services/web/frontend/js/features/ide-redesign/components/rail/rail.tsx

@@ -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 }) => (

+ 0 - 45
services/web/frontend/js/features/ide-redesign/components/settings/editor-settings/new-editor-setting.tsx

@@ -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}
-    />
-  )
-}

+ 3 - 3
services/web/frontend/js/features/ide-redesign/contexts/new-editor-tour-context.tsx

@@ -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> = ({

+ 1 - 8
services/web/frontend/js/features/ide-redesign/contexts/settings-modal-context.tsx

@@ -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(

+ 1 - 12
services/web/frontend/js/features/ide-redesign/utils/new-editor-utils.ts

@@ -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 = () => {

+ 0 - 4
services/web/locales/en.json

@@ -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 Overleaf’s 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 can’t be applied",
   "the_overleaf_color_scheme": "The __appName__ color scheme",

+ 25 - 10
services/web/test/frontend/components/pdf-preview/pdf-logs-entries.spec.tsx

@@ -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',

+ 62 - 49
services/web/test/frontend/components/pdf-preview/pdf-preview.spec.tsx

@@ -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>
       )
 

+ 1 - 0
services/web/test/frontend/features/editor-navigation-toolbar/components/layout-dropdown-button.test.tsx

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

+ 4 - 5
services/web/test/frontend/features/file-tree/components/file-tree-folder.spec.tsx

@@ -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()))

+ 4 - 3
services/web/test/frontend/features/file-tree/components/file-tree-item/file-tree-item-inner.spec.tsx

@@ -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')
     })
   })

+ 4 - 75
services/web/test/frontend/features/file-tree/components/file-tree-item/file-tree-item-name.spec.tsx

@@ -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,53 +16,12 @@ 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')}
-          />
-        </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"
@@ -73,36 +32,6 @@ describe('<FileTreeItemName />', function () {
       </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)
-    })
+    cy.findByRole('button').should('not.exist')
   })
 })

+ 8 - 8
services/web/test/frontend/features/file-tree/flows/context-menu.spec.tsx

@@ -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',
     })

+ 3 - 3
services/web/test/frontend/features/file-tree/flows/create-folder.spec.tsx

@@ -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')
   })
 

+ 2 - 2
services/web/test/frontend/features/file-tree/flows/delete-entity.spec.tsx

@@ -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')

+ 2 - 2
services/web/test/frontend/features/file-tree/flows/rename-entity.spec.tsx

@@ -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')
 

+ 1 - 3
services/web/test/frontend/features/review-panel/review-panel.spec.tsx

@@ -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')
     })