diff --git a/frontend/packages/ux-editor/src/App.test.tsx b/frontend/packages/ux-editor/src/App.test.tsx index 6d3ce7a4e11..95844155445 100644 --- a/frontend/packages/ux-editor/src/App.test.tsx +++ b/frontend/packages/ux-editor/src/App.test.tsx @@ -52,6 +52,38 @@ describe('App', () => { renderApp(mockQueries); await waitForLoadingToFinish(); }); + + it('should render layoutSetsSelector when component has errors', async () => { + const mockGetDataModelMetadata = jest.fn().mockImplementation(() => Promise.reject()); + renderApp({ ...mockQueries, getDataModelMetadata: mockGetDataModelMetadata }); + await waitForLoadingToFinish(); + const layoutSetsContainer = screen.getByRole('combobox', { + name: textMock('left_menu.layout_dropdown_menu_label'), + }); + expect(layoutSetsContainer).toBeInTheDocument(); + }); + + it.each(['layout_sets', 'data_model', 'widget'])( + 'should render errorPage for %s when component has errors', + async (resource) => { + const errorQueries = { + layout_sets: { getLayoutSets: jest.fn().mockImplementation(() => Promise.reject()) }, + data_model: { getDataModelMetadata: jest.fn().mockImplementation(() => Promise.reject()) }, + widget: { getWidgetSettings: jest.fn().mockImplementation(() => Promise.reject()) }, + }; + const errorQuery = errorQueries[resource]; + + renderApp({ ...mockQueries, ...errorQuery }); + await waitForLoadingToFinish(); + + expect( + screen.getByText( + textMock('general.fetch_error_title') + ' ' + textMock(`general.${resource}`), + ), + ).toBeInTheDocument(); + expect(screen.getByText(textMock('general.fetch_error_message'))).toBeInTheDocument(); + }, + ); }); const waitForLoadingToFinish = async () => diff --git a/frontend/packages/ux-editor/src/components/Preview/Preview.test.tsx b/frontend/packages/ux-editor/src/components/Preview/Preview.test.tsx index d9c8a210a65..69eeb5a418f 100644 --- a/frontend/packages/ux-editor/src/components/Preview/Preview.test.tsx +++ b/frontend/packages/ux-editor/src/components/Preview/Preview.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { Preview } from './Preview'; -import { screen } from '@testing-library/react'; +import { screen, waitForElementToBeRemoved } from '@testing-library/react'; import type { ExtendedRenderOptions } from '../../testing/mocks'; import { renderWithProviders } from '../../testing/mocks'; import { textMock } from '@studio/testing/mocks/i18nMock'; @@ -10,13 +10,12 @@ import { previewPage } from 'app-shared/api/paths'; import { TASKID_FOR_STATELESS_APPS } from 'app-shared/constants'; import { app, org } from '@studio/testing/testids'; -jest.mock('app-shared/api/mutations', () => ({ - createPreviewInstance: jest.fn().mockReturnValue(Promise.resolve({ id: 1 })), -})); - describe('Preview', () => { - it('Renders an iframe with the ref from AppContext', () => { + it('Renders an iframe with the ref from AppContext', async () => { render(); + await waitForElementToBeRemoved(() => + screen.queryByTitle(textMock('preview.loading_preview_controller')), + ); expect(screen.getByTitle(textMock('ux_editor.preview'))).toBe( appContextMock.previewIframeRef.current, ); @@ -25,6 +24,9 @@ describe('Preview', () => { it('should be able to toggle between mobile and desktop view', async () => { const user = userEvent.setup(); render(); + await waitForElementToBeRemoved(() => + screen.queryByTitle(textMock('preview.loading_preview_controller')), + ); const switchButton = screen.getByRole('checkbox', { name: textMock('ux_editor.mobilePreview'), @@ -36,7 +38,7 @@ describe('Preview', () => { expect(switchButton).toBeChecked(); }); - it('should render a message when no page is selected', () => { + it('should render a message when no page is selected', async () => { render({ appContextProps: { selectedFormLayoutName: undefined, @@ -45,8 +47,11 @@ describe('Preview', () => { expect(screen.getByText(textMock('ux_editor.no_components_selected'))).toBeInTheDocument(); }); - it('Renders the information alert with preview being limited', () => { + it('Renders the information alert with preview being limited', async () => { render(); + await waitForElementToBeRemoved(() => + screen.queryByTitle(textMock('preview.loading_preview_controller')), + ); const previewLimitationsAlert = screen.getByText(textMock('preview.limitations_info')); expect(previewLimitationsAlert).toBeInTheDocument(); @@ -65,6 +70,9 @@ describe('Preview', () => { it('should be possible to toggle preview window', async () => { const user = userEvent.setup(); const view = render(); + await waitForElementToBeRemoved(() => + screen.queryByTitle(textMock('preview.loading_preview_controller')), + ); const hidePreviewButton = screen.getByRole('button', { name: textMock('ux_editor.close_preview'), @@ -83,8 +91,16 @@ describe('Preview', () => { expect(showPreviewButton).not.toBeInTheDocument(); }); + it('shows a spinner when preview instance is loading', () => { + render(); + expect(screen.getByTitle(textMock('preview.loading_preview_controller'))).toBeInTheDocument(); + }); + it('reloads preview when the selected form layout name changes', async () => { render(); + await waitForElementToBeRemoved(() => + screen.queryByTitle(textMock('preview.loading_preview_controller')), + ); expect(appContextMock.previewIframeRef?.current?.src).toBe( 'http://localhost' + previewPage( @@ -93,6 +109,7 @@ describe('Preview', () => { appContextMock.selectedFormLayoutSetName, TASKID_FOR_STATELESS_APPS, appContextMock.selectedFormLayoutName, + mockInstanceId, ), ); @@ -100,6 +117,9 @@ describe('Preview', () => { appContextMock.selectedFormLayoutName = newSelectedFormLayoutName; render(); + await waitForElementToBeRemoved(() => + screen.queryByTitle(textMock('preview.loading_preview_controller')), + ); expect(appContextMock.previewIframeRef.current.src).toBe( 'http://localhost' + previewPage( @@ -108,14 +128,24 @@ describe('Preview', () => { appContextMock.selectedFormLayoutSetName, TASKID_FOR_STATELESS_APPS, newSelectedFormLayoutName, + mockInstanceId, ), ); }); }); const collapseToggle = jest.fn(); +const mockInstanceId = '1'; export const render = (options: Partial = {}) => { + options = { + ...options, + queries: { + createPreviewInstance: jest + .fn() + .mockImplementation(() => Promise.resolve({ id: mockInstanceId })), + }, + }; return renderWithProviders( , options, diff --git a/frontend/packages/ux-editor/src/components/Preview/Preview.tsx b/frontend/packages/ux-editor/src/components/Preview/Preview.tsx index 904cf6f4e88..7c3a8bb587d 100644 --- a/frontend/packages/ux-editor/src/components/Preview/Preview.tsx +++ b/frontend/packages/ux-editor/src/components/Preview/Preview.tsx @@ -108,7 +108,7 @@ const PreviewFrame = () => { }; }, [previewIframeRef]); - if (createInstancePending) { + if (createInstancePending || !instance) { return ( {createInstanceError ? (