Skip to content

Commit 0177508

Browse files
chore: set up sharing of react via module federation in studio (#31129)
* chore: set up sharing of react via module federation in studio * PR comments
1 parent a6e2efc commit 0177508

16 files changed

+192
-85
lines changed

packages/app/cypress/e2e/cypress-in-cypress-component.cy.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ describe('Cypress In Cypress CT', { viewportWidth: 1500, defaultCommandTimeout:
5555

5656
// Temporarily removed from CT since it doesn't work. Invert this assertion when completing https://github.com/cypress-io/cypress/issues/24549
5757
cy.get('.hook-open-in-ide').should('not.exist')
58+
59+
cy.get('#unified-runner').should('have.attr', 'style', 'width: 500px; height: 500px; transform: scale(1); position: absolute; margin-left: 225px;')
5860
})
5961

6062
it('navigation between specs and other parts of the app works', () => {

packages/app/cypress/e2e/cypress-in-cypress-e2e.cy.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ describe('Cypress In Cypress E2E', { viewportWidth: 1500, defaultCommandTimeout:
7171
})
7272

7373
cy.get('.hook-open-in-ide').should('exist')
74+
75+
cy.get('#unified-runner').should('have.attr', 'style', 'width: 1000px; height: 660px; transform: scale(0.769697); position: absolute; margin-left: -25px;')
7476
})
7577

7678
it('navigation between specs and other parts of the app works', () => {

packages/app/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
"@headlessui/vue": "1.4.0",
3535
"@iconify-json/mdi": "1.1.63",
3636
"@intlify/unplugin-vue-i18n": "4.0.0",
37-
"@module-federation/vite": "^1.2.2",
37+
"@module-federation/runtime": "^0.8.11",
3838
"@packages/data-context": "0.0.0-development",
3939
"@packages/frontend-shared": "0.0.0-development",
4040
"@packages/graphql": "0.0.0-development",

packages/app/src/runner/ResizablePanels.cy.tsx

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const slotContents = {
2525
panel1: () => <div class="h-full bg-emerald-100">panel1</div>,
2626
panel2: () => <div class="h-full bg-purple-300">panel2</div>,
2727
panel3: () => <div class="grow h-full bg-indigo-100">panel3</div>,
28+
panel4: () => <div class="h-full bg-yellow-100">panel4</div>,
2829
}
2930

3031
describe('<ResizablePanels />', { viewportWidth: 1500, defaultCommandTimeout: 4000 }, () => {
@@ -169,7 +170,7 @@ describe('<ResizablePanels />', { viewportWidth: 1500, defaultCommandTimeout: 40
169170
assertWidth('panel3', 550)
170171
})
171172

172-
it('Panel 3 resizes correctly when both panels are hidden', () => {
173+
it('Panel 3 resizes correctly when all panels are hidden', () => {
173174
cy.mount(() => (
174175
<div class="h-screen">
175176
<ResizablePanels
@@ -184,5 +185,23 @@ describe('<ResizablePanels />', { viewportWidth: 1500, defaultCommandTimeout: 40
184185
cy.contains('panel2').should('not.be.visible')
185186
assertWidth('panel3', 1500)
186187
})
188+
189+
it('Panel 3 resizes correctly when panels 1 and 2 are hidden and panel 4 is shown', () => {
190+
cy.mount(() => (
191+
<div class="h-screen">
192+
<ResizablePanels
193+
maxTotalWidth={1500}
194+
v-slots={slotContents}
195+
showPanel1={false}
196+
showPanel2={false}
197+
showPanel4={true}
198+
/>
199+
</div>))
200+
201+
cy.contains('panel1').should('not.be.visible')
202+
cy.contains('panel2').should('not.be.visible')
203+
cy.contains('panel4').should('be.visible')
204+
assertWidth('panel3', 1200)
205+
})
187206
})
188207
})

packages/app/src/runner/ResizablePanels.vue

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,18 @@
5555
:width="panel3width"
5656
/>
5757
</div>
58+
59+
<div
60+
v-show="showPanel4"
61+
data-cy="studio-panel"
62+
class="h-full bg-gray-100 relative"
63+
:style="{width: `${panel4Width}px`}"
64+
>
65+
<slot
66+
name="panel4"
67+
:width="panel4Width"
68+
/>
69+
</div>
5870
</div>
5971
</template>
6072

@@ -72,6 +84,7 @@ import type { DraggablePanel } from './useRunnerStyle'
7284
const props = withDefaults(defineProps<{
7385
showPanel1?: boolean // specsList in runner
7486
showPanel2?: boolean // reporter in runner
87+
showPanel4?: boolean // studio in runner
7588
initialPanel1Width?: number
7689
initialPanel2Width?: number
7790
minPanel1Width?: number
@@ -82,6 +95,7 @@ const props = withDefaults(defineProps<{
8295
}>(), {
8396
showPanel1: true,
8497
showPanel2: true,
98+
showPanel4: false,
8599
initialPanel1Width: runnerConstants.defaultSpecListWidth,
86100
initialPanel2Width: runnerConstants.defaultReporterWidth,
87101
minPanel1Width: 200,
@@ -146,6 +160,14 @@ const maxPanel1Width = computed(() => {
146160
return props.maxTotalWidth - unavailableWidth
147161
})
148162
163+
const panel4Width = computed(() => {
164+
if (!props.showPanel4) {
165+
return 0
166+
}
167+
168+
return runnerConstants.defaultStudioWidth
169+
})
170+
149171
const panel1Width = computed(() => {
150172
if (!props.showPanel1) {
151173
return 0
@@ -155,13 +177,13 @@ const panel1Width = computed(() => {
155177
})
156178
157179
const maxPanel2Width = computed(() => {
158-
const unavailableWidth = panel1Width.value + props.minPanel3Width
180+
const unavailableWidth = panel1Width.value + props.minPanel3Width + panel4Width.value
159181
160182
return props.maxTotalWidth - unavailableWidth
161183
})
162184
163185
const panel3width = computed(() => {
164-
const panel3SpaceAvailable = props.maxTotalWidth - panel1Width.value - panel2Width.value
186+
const panel3SpaceAvailable = props.maxTotalWidth - panel1Width.value - panel2Width.value - panel4Width.value
165187
166188
// minimumWithMargin - if panel 3 would end up below the minimum allowed size
167189
// due to window resizing, forcing the minimum width will create a horizontal scroll
@@ -176,7 +198,7 @@ function handleResizeEnd (panel: DraggablePanel) {
176198
}
177199
178200
function isNewWidthAllowed (mouseClientX: number, panel: DraggablePanel) {
179-
const isMaxWidthSmall = props.maxTotalWidth < (panel1Width.value + panel2Width.value + props.minPanel3Width)
201+
const isMaxWidthSmall = props.maxTotalWidth < (panel1Width.value + panel2Width.value + props.minPanel3Width + panel4Width.value)
180202
const fallbackWidth = 50
181203
182204
if (panel === 'panel1') {
@@ -206,6 +228,12 @@ watchEffect(() => {
206228
} else if (props.showPanel1) {
207229
emit('panelWidthUpdated', { panel: 'panel1', width: cachedPanel1Width.value })
208230
}
231+
232+
if (!props.showPanel4) {
233+
emit('panelWidthUpdated', { panel: 'panel4', width: 0 })
234+
} else if (props.showPanel4) {
235+
emit('panelWidthUpdated', { panel: 'panel4', width: panel4Width.value })
236+
}
209237
})
210238
211239
</script>

packages/app/src/runner/SpecRunnerOpenMode.vue

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
:min-panel3-width="minWidths.aut"
3232
:show-panel1="runnerUiStore.isSpecsListOpen && !screenshotStore.isScreenshotting"
3333
:show-panel2="!screenshotStore.isScreenshotting && !hideCommandLog"
34+
:show-panel4="shouldShowStudioPanel"
3435
@resize-end="handleResizeEnd"
3536
@panel-width-updated="handlePanelWidthUpdated"
3637
>
@@ -96,12 +97,15 @@
9697
/>
9798
<ScreenshotHelperPixels />
9899
</template>
100+
<template #panel4>
101+
<StudioPanel v-show="shouldShowStudioPanel" />
102+
</template>
99103
</ResizablePanels>
100104
</AdjustRunnerStyleDuringScreenshot>
101105
</template>
102106

103107
<script lang="ts" setup>
104-
import { computed, onBeforeUnmount, onMounted, watchEffect } from 'vue'
108+
import { computed, onBeforeUnmount, onMounted } from 'vue'
105109
import { REPORTER_ID, RUNNER_ID } from './utils'
106110
import InlineSpecList from '../specs/InlineSpecList.vue'
107111
import { getAutIframeModel, getEventManager } from '.'
@@ -130,6 +134,7 @@ import { runnerConstants } from './runner-constants'
130134
import StudioInstructionsModal from './studio/StudioInstructionsModal.vue'
131135
import StudioSaveModal from './studio/StudioSaveModal.vue'
132136
import { useStudioStore } from '../store/studio-store'
137+
import StudioPanel from '../studio/StudioPanel.vue'
133138
134139
const {
135140
preferredMinimumPanelWidth,
@@ -148,6 +153,7 @@ fragment SpecRunner_Preferences on Query {
148153
autoScrollingEnabled
149154
reporterWidth
150155
specListWidth
156+
studioWidth
151157
}
152158
}
153159
}
@@ -220,6 +226,10 @@ const reporterWidthPreferences = computed(() => {
220226
return props.gql.localSettings.preferences.reporterWidth ?? runnerUiStore.reporterWidth
221227
})
222228
229+
const studioWidthPreferences = computed(() => {
230+
return props.gql.localSettings.preferences.studioWidth ?? runnerUiStore.studioWidth
231+
})
232+
223233
const isSpecsListOpenPreferences = computed(() => {
224234
return props.gql.localSettings.preferences.isSpecsListOpen ?? false
225235
})
@@ -228,6 +238,10 @@ const studioStatus = computed(() => {
228238
return props.gql.studio?.status
229239
})
230240
241+
const shouldShowStudioPanel = computed(() => {
242+
return studioStatus.value === 'INITIALIZED' && studioStore.isActive
243+
})
244+
231245
const hideCommandLog = runnerUiStore.hideCommandLog
232246
233247
// watch active spec, and re-run if it changes!
@@ -245,6 +259,7 @@ if (!hideCommandLog) {
245259
preferences.update('isSpecsListOpen', isSpecsListOpenPreferences.value)
246260
preferences.update('reporterWidth', reporterWidthPreferences.value)
247261
preferences.update('specListWidth', specsListWidthPreferences.value)
262+
preferences.update('studioWidth', studioWidthPreferences.value)
248263
// 👆 we must update these preferences before calling useRunnerStyle, to make sure that values from GQL
249264
// will be available during the initial calculation that useRunnerStyle does
250265
}
@@ -300,18 +315,6 @@ function openFile () {
300315
})
301316
}
302317
303-
watchEffect(() => {
304-
if (studioStatus.value === 'INITIALIZED') {
305-
import('app-studio').then(({ mountTestGenerationPanel }) => {
306-
// eslint-disable-next-line no-console
307-
console.log('Studio loaded', mountTestGenerationPanel)
308-
}).catch((err) => {
309-
// eslint-disable-next-line no-console
310-
console.error('Error loading Studio', err)
311-
})
312-
}
313-
})
314-
315318
onMounted(() => {
316319
const eventManager = getEventManager()
317320

packages/app/src/runner/runner-constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export const runnerConstants = {
22
defaultSpecListWidth: 280,
33
defaultReporterWidth: 450,
4+
defaultStudioWidth: 300,
45
preferredMinimumPanelWidth: 200,
56
absoluteAutMinimum: 100,
67
absoluteSpecListMinimum: 50,

packages/app/src/runner/useRunnerStyle.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { useAutStore, useRunnerUiStore } from '../store'
66
import { useScreenshotStore } from '../store/screenshot-store'
77
import { runnerConstants } from './runner-constants'
88

9-
export type ResizablePanelName = 'panel1' | 'panel2' | 'panel3'
9+
export type ResizablePanelName = 'panel1' | 'panel2' | 'panel3' | 'panel4'
1010

1111
export type DraggablePanel = Exclude<ResizablePanelName, 'panel3'>
1212

@@ -17,6 +17,7 @@ const autMargin = 16
1717
// so that we only save to GQL when the resizing has ended
1818
const reporterWidth = ref<number>(0)
1919
const specListWidth = ref<number>(0)
20+
const studioWidth = ref<number>(0)
2021

2122
export const useRunnerStyle = () => {
2223
const { width: windowWidth, height: windowHeight } = useWindowSize()
@@ -26,10 +27,11 @@ export const useRunnerStyle = () => {
2627
const screenshotStore = useScreenshotStore()
2728
const autStore = useAutStore()
2829

29-
const { reporterWidth: initialReporterWidth, specListWidth: initialSpecsListWidth } = runnerUIStore
30+
const { reporterWidth: initialReporterWidth, specListWidth: initialSpecsListWidth, studioWidth: initialStudioWidth } = runnerUIStore
3031

3132
reporterWidth.value = initialReporterWidth
3233
specListWidth.value = initialSpecsListWidth
34+
studioWidth.value = initialStudioWidth
3335

3436
const containerWidth = computed(() => {
3537
const miscBorders = 4
@@ -47,7 +49,7 @@ export const useRunnerStyle = () => {
4749
nonAutWidth += (autMargin * 2)
4850
}
4951

50-
nonAutWidth += reporterWidth.value + specListWidth.value + miscBorders
52+
nonAutWidth += reporterWidth.value + specListWidth.value + studioWidth.value + miscBorders
5153
}
5254

5355
const containerWidth = windowWidth.value - nonAutWidth
@@ -117,6 +119,8 @@ export function useResizablePanels () {
117119
const handleResizeEnd = async (panel: DraggablePanel) => {
118120
if (panel === 'panel1') {
119121
await preferences.update('specListWidth', specListWidth.value)
122+
} else if (panel === 'panel4') {
123+
await preferences.update('studioWidth', studioWidth.value)
120124
} else {
121125
await preferences.update('reporterWidth', reporterWidth.value)
122126
}
@@ -125,6 +129,8 @@ export function useResizablePanels () {
125129
const handlePanelWidthUpdated = ({ panel, width }: { panel: DraggablePanel, width: number }) => {
126130
if (panel === 'panel1') {
127131
specListWidth.value = width
132+
} else if (panel === 'panel4') {
133+
studioWidth.value = width
128134
} else {
129135
reporterWidth.value = width
130136
}

packages/app/src/store/runner-ui-store.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export interface RunnerUiState {
2424
isSpecsListOpen: boolean
2525
specListWidth: number
2626
reporterWidth: number
27+
studioWidth: number
2728
automationStatus: AutomationStatus
2829
randomString: string
2930
hideCommandLog: boolean
@@ -40,6 +41,7 @@ export const useRunnerUiStore = defineStore({
4041
isSpecsListOpen: false,
4142
specListWidth: runnerConstants.defaultSpecListWidth,
4243
reporterWidth: runnerConstants.defaultReporterWidth,
44+
studioWidth: runnerConstants.defaultStudioWidth,
4345
automationStatus: automation.CONNECTING,
4446
randomString: `${Math.random()}`,
4547
hideCommandLog: window.__CYPRESS_CONFIG__.hideCommandLog,

0 commit comments

Comments
 (0)