Files
Verso/services/web/test/frontend/shared/hooks/use-detach-layout.spec.tsx
T
Rebeka DekanyandCopybot d751b88e6b Bootstrap files and folders cleanup (#27692)
* Remove icons folder

* Create folders for badge, button, and dropdown components

* Remove Bootstrap 5 from test

* Rename `getBootstrap5Breakpoint` to `getBootstrapBreakpoint`

* Cleanup and update BS 5 comments

* Move components to the shared folder

* Rename `tooltips-bs5` to `tooltip`

* Remove `-bs5` suffix

* Fix path

* Delete BS3 version file

* Rename `_form_marketing-bootstrap-5` to `_form_marketing`

* Delete BS3 version file

* Rename `_contact_general_modal-marketing-bootstrap-5` to `_contact_general_modal-marketing`

* Delete BS3 version file

* Rename `_contact_modal-marketing-bootstrap-5` to `_contact_modal-marketing`

* Delete BS3 version file

* Rename `thin-footer-bootstrap-5` to `thin-footer`

* Delete BS3 version file

* Rename `language-picker-bootstrap-5` to `language-picker`

* Rename `fat-footer-react-bootstrap-5` to `fat-footer-react`

* Delete BS3 version file

* Rename `navbar-marketing-bootstrap-5` to `navbar-marketing`

* Rename `navbar-marketing-react-bootstrap-5` to `navbar-marketing-react`

* Delete BS3 version file

* Rename `layout-website-redesign-cms-bootstrap-5` to `layout-website-redesign-cms`

* Source format

* Fix path

GitOrigin-RevId: cf0f5db7c84cf545c69213dcc271d9ff17fe5db7
2025-08-11 08:06:16 +00:00

250 lines
7.1 KiB
TypeScript

import useDetachLayout from '../../../../frontend/js/shared/hooks/use-detach-layout'
import { detachChannel, testDetachChannel } from '../../helpers/detach-channel'
import { EditorProviders } from '../../helpers/editor-providers'
import OLFormGroup from '@/shared/components/ol/ol-form-group'
import OLFormCheckbox from '@/shared/components/ol/ol-form-checkbox'
import OLFormLabel from '@/shared/components/ol/ol-form-label'
import OLButton from '@/shared/components/ol/ol-button'
const DetachLayoutTest = () => {
const { role, reattach, detach, isLinked, isLinking, isRedundant } =
useDetachLayout()
return (
<fieldset>
<legend>
role: <span id="role">{role || 'none'}</span>
</legend>
<OLFormGroup>
<OLFormCheckbox id="isLinked" inline checked={isLinked} readOnly />
<OLFormLabel>linked</OLFormLabel>
</OLFormGroup>
<OLFormGroup>
<OLFormCheckbox id="isLinking" inline checked={isLinking} readOnly />
<OLFormLabel>linking</OLFormLabel>
</OLFormGroup>
<OLFormGroup>
<OLFormCheckbox
id="isRedundant"
inline
checked={isRedundant}
readOnly
/>
<OLFormLabel>redundant</OLFormLabel>
</OLFormGroup>
<OLButton id="reattach" onClick={reattach}>
reattach
</OLButton>
<OLButton id="detach" onClick={detach}>
detach
</OLButton>
</fieldset>
)
}
describe('useDetachLayout', function () {
beforeEach(function () {
window.metaAttributesCache.set('ol-preventCompileOnLoad', true)
cy.stub(window, 'open').as('openWindow')
cy.stub(window, 'close').as('closeWindow')
cy.interceptEvents()
})
it('detaching', function () {
// 1. create hook in normal mode
cy.mount(
<EditorProviders>
<DetachLayoutTest />
</EditorProviders>
)
cy.get('#isLinked').should('not.be.checked')
cy.get('#isLinking').should('not.be.checked')
cy.get('#role').should('have.text', 'none')
// 2. detach
cy.get('#detach').click()
cy.get('@openWindow').should(
'have.been.calledOnceWith',
Cypress.sinon.match(/\/detached/),
'_blank'
)
cy.get('#isLinked').should('not.be.checked')
cy.get('#isLinking').should('be.checked')
cy.get('#role').should('have.text', 'detacher')
})
it('detacher role', function () {
// 1. create hook in detacher mode
window.metaAttributesCache.set('ol-detachRole', 'detacher')
cy.mount(
<EditorProviders>
<DetachLayoutTest />
</EditorProviders>
)
cy.get('#isLinked').should('not.be.checked')
cy.get('#isLinking').should('not.be.checked')
cy.get('#role').should('have.text', 'detacher')
cy.spy(detachChannel, 'postMessage').as('postDetachMessage')
cy.wrap(null).then(() => {
testDetachChannel.postMessage({
role: 'detached',
event: 'connected',
})
})
// 2. simulate connected detached tab
cy.get('@postDetachMessage').should('have.been.calledWith', {
role: 'detacher',
event: 'up',
})
cy.get('#isLinked').should('be.checked')
cy.get('#isLinking').should('not.be.checked')
cy.get('#role').should('have.text', 'detacher')
// 3. simulate closed detached tab
cy.wrap(null).then(() => {
testDetachChannel.postMessage({
role: 'detached',
event: 'closed',
})
})
cy.get('#isLinked').should('not.be.checked')
cy.get('#isLinking').should('not.be.checked')
cy.get('#role').should('have.text', 'detacher')
// 4. simulate up detached tab
cy.wrap(null).then(() => {
testDetachChannel.postMessage({
role: 'detached',
event: 'up',
})
})
cy.get('#isLinked').should('be.checked')
cy.get('#isLinking').should('not.be.checked')
cy.get('#role').should('have.text', 'detacher')
// 5. reattach
cy.get('@postDetachMessage').invoke('resetHistory')
cy.get('#reattach').click()
cy.get('#isLinked').should('not.be.checked')
cy.get('#isLinking').should('not.be.checked')
cy.get('#role').should('have.text', 'none')
cy.get('@postDetachMessage').should('have.been.calledWith', {
role: 'detacher',
event: 'reattach',
})
})
it('reset detacher role when other detacher tab connects', function () {
// 1. create hook in detacher mode
window.metaAttributesCache.set('ol-detachRole', 'detacher')
cy.mount(
<EditorProviders>
<DetachLayoutTest />
</EditorProviders>
)
cy.get('#isLinked').should('not.be.checked')
cy.get('#isLinking').should('not.be.checked')
cy.get('#role').should('have.text', 'detacher')
// 2. simulate other detacher tab
cy.wrap(null).then(() => {
testDetachChannel.postMessage({
role: 'detacher',
event: 'up',
})
})
cy.get('#isRedundant').should('be.checked')
cy.get('#role').should('have.text', 'none')
})
it('detached role', function () {
// 1. create hook in detached mode
window.metaAttributesCache.set('ol-detachRole', 'detached')
cy.mount(
<EditorProviders>
<DetachLayoutTest />
</EditorProviders>
)
cy.get('#isLinked').should('not.be.checked')
cy.get('#isLinking').should('not.be.checked')
cy.get('#role').should('have.text', 'detached')
// 2. simulate up detacher tab
cy.wrap(null).then(() => {
testDetachChannel.postMessage({
role: 'detacher',
event: 'up',
})
})
cy.get('#isLinked').should('be.checked')
cy.get('#isLinking').should('not.be.checked')
cy.get('#role').should('have.text', 'detached')
// 3. simulate closed detacher tab
cy.wrap(null).then(() => {
testDetachChannel.postMessage({
role: 'detacher',
event: 'closed',
})
})
cy.get('#isLinked').should('not.be.checked')
cy.get('#isLinking').should('not.be.checked')
cy.get('#role').should('have.text', 'detached')
// 4. simulate up detacher tab
cy.wrap(null).then(() => {
testDetachChannel.postMessage({
role: 'detacher',
event: 'up',
})
})
cy.get('#isLinked').should('be.checked')
cy.get('#isLinking').should('not.be.checked')
cy.get('#role').should('have.text', 'detached')
// 5. simulate closed detached tab
cy.spy(detachChannel, 'postMessage').as('postDetachMessage')
cy.wrap(null).then(() => {
testDetachChannel.postMessage({
role: 'detached',
event: 'closed',
})
})
cy.get('#isLinked').should('be.checked')
cy.get('#isLinking').should('not.be.checked')
cy.get('#role').should('have.text', 'detached')
cy.get('@postDetachMessage').should('have.been.calledWith', {
role: 'detached',
event: 'up',
})
// 6. simulate reattach event
cy.get('@postDetachMessage').invoke('resetHistory')
cy.wrap(null).then(() => {
testDetachChannel.postMessage({
role: 'detacher',
event: 'reattach',
})
})
cy.get('#isLinked').should('not.be.checked')
cy.get('#isLinking').should('not.be.checked')
cy.get('#role').should('have.text', 'detached')
cy.get('@closeWindow').should('have.been.called')
})
})