mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-14 14:13:43 +01:00
[web] Add offline indicator to toolbar (#35368)
GitOrigin-RevId: 81127bff21afb6aadcf175ba1767a2629f01d747
This commit is contained in:
+83
@@ -0,0 +1,83 @@
|
||||
import OfflineIndicator from '@/features/ide-react/components/toolbar/offline-indicator'
|
||||
import { UnsavedDocsContext } from '@/features/ide-react/context/unsaved-docs-context'
|
||||
import { IdeReactContext } from '@/features/ide-react/context/ide-react-context'
|
||||
import { IdeEventEmitter } from '@/features/ide-react/create-ide-event-emitter'
|
||||
import { SplitTestProvider } from '@/shared/context/split-test-context'
|
||||
|
||||
const defaultIdeReactContextValue = {
|
||||
projectId: 'test-project',
|
||||
eventEmitter: new IdeEventEmitter(),
|
||||
startedFreeTrial: false,
|
||||
setStartedFreeTrial: () => {},
|
||||
reportError: () => {},
|
||||
projectJoined: true,
|
||||
permissionsLevel: 'owner' as const,
|
||||
setPermissionsLevel: () => {},
|
||||
outOfSync: false,
|
||||
setOutOfSync: () => {},
|
||||
}
|
||||
|
||||
const defaultUnsavedDocsContextValue = {
|
||||
unsavedDocs: new Map<string, number>(),
|
||||
isLocked: false,
|
||||
}
|
||||
|
||||
const mount = ({
|
||||
unsavedDocs = new Map<string, number>(),
|
||||
}: {
|
||||
unsavedDocs?: Map<string, number>
|
||||
} = {}) => {
|
||||
cy.mount(
|
||||
<SplitTestProvider>
|
||||
<IdeReactContext.Provider value={defaultIdeReactContextValue}>
|
||||
<UnsavedDocsContext.Provider
|
||||
value={{ ...defaultUnsavedDocsContextValue, unsavedDocs }}
|
||||
>
|
||||
<OfflineIndicator />
|
||||
</UnsavedDocsContext.Provider>
|
||||
</IdeReactContext.Provider>
|
||||
</SplitTestProvider>
|
||||
)
|
||||
}
|
||||
|
||||
const enableFlag = () => {
|
||||
cy.window().then(win => {
|
||||
win.metaAttributesCache.set('ol-splitTestVariants', {
|
||||
'intermittent-connection-improvements': 'enabled',
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const unsavedDoc = () => new Map<string, number>([['doc-1', 20]])
|
||||
|
||||
describe('<OfflineIndicator />', function () {
|
||||
it('is hidden when the feature flag is disabled', function () {
|
||||
mount({ unsavedDocs: unsavedDoc() })
|
||||
cy.findByText('You’re offline').should('not.exist')
|
||||
cy.findByRole('status').should('not.exist')
|
||||
})
|
||||
|
||||
it('is hidden when the flag is enabled but there are no unsaved docs', function () {
|
||||
enableFlag()
|
||||
mount()
|
||||
cy.findByText('You’re offline').should('not.exist')
|
||||
cy.findByRole('status').should('be.empty')
|
||||
})
|
||||
|
||||
it('is shown when the flag is enabled and there are unsaved docs', function () {
|
||||
enableFlag()
|
||||
mount({ unsavedDocs: unsavedDoc() })
|
||||
cy.findAllByText('You’re offline').first().should('be.visible')
|
||||
})
|
||||
|
||||
it('announces the offline status to screen readers via a live region', function () {
|
||||
enableFlag()
|
||||
mount({ unsavedDocs: unsavedDoc() })
|
||||
cy.findByRole('status').within(() => {
|
||||
cy.findByText('You’re offline').should('exist')
|
||||
cy.findByText(
|
||||
'Your changes are saved in the browser. We’ll sync your work when you’re back online.'
|
||||
).should('exist')
|
||||
})
|
||||
})
|
||||
})
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
import { UnsavedDocs } from '@/features/ide-react/components/unsaved-docs/unsaved-docs'
|
||||
import { UnsavedDocsContext } from '@/features/ide-react/context/unsaved-docs-context'
|
||||
import { GlobalAlertsProvider } from '@/features/ide-react/context/global-alerts-context'
|
||||
import { FileTreePathContext } from '@/features/file-tree/contexts/file-tree-path'
|
||||
import { ConnectionContext } from '@/features/ide-react/context/connection-context'
|
||||
import { SplitTestProvider } from '@/shared/context/split-test-context'
|
||||
|
||||
const defaultUnsavedDocsContextValue = {
|
||||
unsavedDocs: new Map<string, number>([['doc1', 16]]),
|
||||
isLocked: false,
|
||||
}
|
||||
|
||||
const mockSocket = {
|
||||
socket: { transport: { name: 'websocket' } },
|
||||
} as any
|
||||
|
||||
const mockConnectionContextValue = {
|
||||
socket: mockSocket,
|
||||
connectionState: { readyState: WebSocket.OPEN },
|
||||
isConnected: true,
|
||||
isStillReconnecting: false,
|
||||
secondsUntilReconnect: () => 0,
|
||||
tryReconnectNow: () => {},
|
||||
registerUserActivity: () => {},
|
||||
closeConnection: () => {},
|
||||
getSocketDebuggingInfo: () => ({ id: '' }),
|
||||
} as any
|
||||
|
||||
const mockFileTreePathContextValue = {
|
||||
dirname: () => '',
|
||||
pathInFolder: (docId: string) => (docId === 'doc1' ? 'main.tex' : null),
|
||||
findEntityByPath: (path: string) =>
|
||||
path === 'main.tex'
|
||||
? { entity: { _id: 'doc1', name: 'main.tex' }, type: 'doc' as const }
|
||||
: null,
|
||||
previewByPath: () => null,
|
||||
}
|
||||
|
||||
const mount = () => {
|
||||
cy.mount(
|
||||
<SplitTestProvider>
|
||||
<GlobalAlertsProvider>
|
||||
<ConnectionContext.Provider value={mockConnectionContextValue}>
|
||||
<FileTreePathContext.Provider value={mockFileTreePathContextValue}>
|
||||
<UnsavedDocsContext.Provider value={defaultUnsavedDocsContextValue}>
|
||||
<UnsavedDocs />
|
||||
</UnsavedDocsContext.Provider>
|
||||
</FileTreePathContext.Provider>
|
||||
</ConnectionContext.Provider>
|
||||
</GlobalAlertsProvider>
|
||||
</SplitTestProvider>
|
||||
)
|
||||
}
|
||||
|
||||
const enableFlag = () => {
|
||||
cy.window().then(win => {
|
||||
win.metaAttributesCache.set('ol-splitTestVariants', {
|
||||
'intermittent-connection-improvements': 'enabled',
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
describe('<UnsavedDocs />', function () {
|
||||
it('shows UnsavedDocsAlert when flag is disabled', function () {
|
||||
mount()
|
||||
cy.findByRole('alert').should('exist')
|
||||
})
|
||||
|
||||
it('suppresses UnsavedDocsAlert when flag is enabled', function () {
|
||||
enableFlag()
|
||||
mount()
|
||||
cy.findByRole('alert').should('not.exist')
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user