From d32e904a9d4ea1517b596134b739c59c553b3583 Mon Sep 17 00:00:00 2001
From: Carlos Emiliano Castro Trejo
<102700317+ccastrotrejo@users.noreply.github.com>
Date: Mon, 27 Jan 2025 09:26:49 -0800
Subject: [PATCH] fix(designer): Render copied tooltip properly (#6463)
* Update component to render properly
* Add unit tests
* Update unit tests
* Update e2e tests
* update unit tests
---
e2e/designer/mock-copypastescope.spec.ts | 2 +
.../lib/ui/CustomNodes/OperationCardNode.tsx | 2 +-
.../src/lib/ui/CustomNodes/ScopeCardNode.tsx | 2 +-
.../DesignerContextualMenu/CopyTooltip.tsx | 36 ++++----
.../DesignerContextualMenu.tsx | 2 +-
.../__test__/CopyTooltip.spec.tsx | 86 +++++++++++++++++++
.../__snapshots__/CopyTooltip.spec.tsx.snap | 67 +++++++++++++++
7 files changed, 176 insertions(+), 21 deletions(-)
create mode 100644 libs/designer/src/lib/ui/common/DesignerContextualMenu/__test__/CopyTooltip.spec.tsx
create mode 100644 libs/designer/src/lib/ui/common/DesignerContextualMenu/__test__/__snapshots__/CopyTooltip.spec.tsx.snap
diff --git a/e2e/designer/mock-copypastescope.spec.ts b/e2e/designer/mock-copypastescope.spec.ts
index f21660b1d74..1ada7b65d00 100644
--- a/e2e/designer/mock-copypastescope.spec.ts
+++ b/e2e/designer/mock-copypastescope.spec.ts
@@ -15,6 +15,8 @@ test(
});
await page.getByTestId('msla-copy-menu-option').click();
+ await expect(page.getByRole('tooltip', { name: 'Copied!' })).toBeVisible();
+ await expect(page.getByTestId('msla-tooltip-location-condition')).toBeVisible();
await page.getByTestId('msla-plus-button-initialize_variable-condition').click();
await page.getByTestId('msla-paste-button-initialize_variable-condition').click();
await page.waitForTimeout(1000);
diff --git a/libs/designer/src/lib/ui/CustomNodes/OperationCardNode.tsx b/libs/designer/src/lib/ui/CustomNodes/OperationCardNode.tsx
index f9af181986c..5ce7a74dab3 100644
--- a/libs/designer/src/lib/ui/CustomNodes/OperationCardNode.tsx
+++ b/libs/designer/src/lib/ui/CustomNodes/OperationCardNode.tsx
@@ -336,7 +336,7 @@ const DefaultNode = ({ targetPosition = Position.Top, sourcePosition = Position.
isLoadingDynamicData={isLoadingDynamicData}
nodeIndex={nodeIndex}
/>
- {showCopyCallout ? : null}
+ {showCopyCallout ? : null}
{showLeafComponents ? (
diff --git a/libs/designer/src/lib/ui/CustomNodes/ScopeCardNode.tsx b/libs/designer/src/lib/ui/CustomNodes/ScopeCardNode.tsx
index 04d051db7cf..a46c97f7f5b 100644
--- a/libs/designer/src/lib/ui/CustomNodes/ScopeCardNode.tsx
+++ b/libs/designer/src/lib/ui/CustomNodes/ScopeCardNode.tsx
@@ -334,7 +334,7 @@ const ScopeCardNode = ({ data, targetPosition = Position.Top, sourcePosition = P
setFocus={shouldFocus}
nodeIndex={nodeIndex}
/>
- {showCopyCallout ? : null}
+ {showCopyCallout ? : null}
{normalizedType === constants.NODE.TYPE.FOREACH && isMonitoringView ? renderLoopsPager : null}
diff --git a/libs/designer/src/lib/ui/common/DesignerContextualMenu/CopyTooltip.tsx b/libs/designer/src/lib/ui/common/DesignerContextualMenu/CopyTooltip.tsx
index 23b7fef04e9..3f0fb5645b2 100644
--- a/libs/designer/src/lib/ui/common/DesignerContextualMenu/CopyTooltip.tsx
+++ b/libs/designer/src/lib/ui/common/DesignerContextualMenu/CopyTooltip.tsx
@@ -1,16 +1,17 @@
-/* eslint-disable react/display-name */
import { Tooltip } from '@fluentui/react-components';
+import { replaceWhiteSpaceWithUnderscore } from '@microsoft/logic-apps-shared';
import { useOnViewportChange } from '@xyflow/react';
-import { useMemo, useRef } from 'react';
+import { useRef } from 'react';
import { useIntl } from 'react-intl';
export interface CopyTooltipProps {
targetRef?: React.RefObject;
location?: { x: number; y: number };
hideTooltip: () => void;
+ id: string;
}
-export const CopyTooltip = ({ targetRef: ref, location, hideTooltip }: CopyTooltipProps) => {
+export const CopyTooltip = ({ targetRef: ref, location, hideTooltip, id }: CopyTooltipProps) => {
useOnViewportChange({ onStart: () => hideTooltip() });
const intl = useIntl();
@@ -22,21 +23,20 @@ export const CopyTooltip = ({ targetRef: ref, location, hideTooltip }: CopyToolt
const locationRef = useRef(null);
- const TooltipComponent = useMemo(
- () => () => (
-
- ),
- [copiedText, ref]
- );
-
return (
-
-
-
+
+
+
);
};
diff --git a/libs/designer/src/lib/ui/common/DesignerContextualMenu/DesignerContextualMenu.tsx b/libs/designer/src/lib/ui/common/DesignerContextualMenu/DesignerContextualMenu.tsx
index 5760ab6e350..e5c0d3b4706 100644
--- a/libs/designer/src/lib/ui/common/DesignerContextualMenu/DesignerContextualMenu.tsx
+++ b/libs/designer/src/lib/ui/common/DesignerContextualMenu/DesignerContextualMenu.tsx
@@ -185,7 +185,7 @@ export const DesignerContextualMenu = () => {
title={title}
setOpen={(o) => setOpen(o)}
/>
- {showCopyCallout ? : null}
+ {showCopyCallout ? : null}
>
);
};
diff --git a/libs/designer/src/lib/ui/common/DesignerContextualMenu/__test__/CopyTooltip.spec.tsx b/libs/designer/src/lib/ui/common/DesignerContextualMenu/__test__/CopyTooltip.spec.tsx
new file mode 100644
index 00000000000..2aeb794787f
--- /dev/null
+++ b/libs/designer/src/lib/ui/common/DesignerContextualMenu/__test__/CopyTooltip.spec.tsx
@@ -0,0 +1,86 @@
+import { render, screen } from '@testing-library/react';
+import { CopyTooltip, CopyTooltipProps } from '../CopyTooltip';
+import { describe, it, expect, vi, afterEach, beforeAll } from 'vitest';
+import React from 'react';
+
+const hideTooltipMock = vi.fn();
+
+vi.mock('@xyflow/react', async () => {
+ const actualIntl = await vi.importActual('@xyflow/react');
+ return {
+ ...actualIntl,
+ useOnViewportChange: vi.fn(() => ({ onStart: hideTooltipMock })),
+ };
+});
+
+vi.mock('react-intl', async () => {
+ const actualIntl = await vi.importActual('react-intl');
+ return {
+ ...actualIntl,
+ useIntl: () => ({
+ formatMessage: vi.fn(() => 'Copied!'),
+ }),
+ };
+});
+
+describe('CopyTooltip', () => {
+ beforeAll(() => {
+ const portalRoot = document.createElement('div');
+ portalRoot.setAttribute('id', 'root');
+ document.body.appendChild(portalRoot);
+ });
+
+ afterEach(() => {
+ vi.clearAllMocks();
+ });
+
+ const renderComponent = (props: Partial = {}) => {
+ const defaultProps: CopyTooltipProps = {
+ hideTooltip: hideTooltipMock,
+ id: 'test-id',
+ ...props,
+ };
+
+ return render();
+ };
+
+ it('should render the tooltip with the correct content', () => {
+ const copiedText = 'Copied!';
+ const location = { x: 100, y: 100 };
+
+ // Render the Tooltip component
+ const { baseElement } = renderComponent({ location });
+
+ // Get the tooltip div and the location div
+ const tooltipDiv = screen.getByRole('tooltip');
+ const tooltipLocationDiv = screen.getByTestId('msla-tooltip-location-test_id');
+
+ // Assert that the tooltip and location div are rendered correctly
+ expect(tooltipDiv).toBeInTheDocument();
+ expect(screen.getByText(copiedText)).toBeVisible();
+ expect(tooltipLocationDiv).toBeInTheDocument();
+ expect(baseElement).toMatchSnapshot();
+ });
+
+ it('should position the tooltip based on the provided location', () => {
+ const location = { x: 100, y: 100 };
+
+ // Render the Tooltip component
+ const { baseElement } = renderComponent({ location });
+
+ // Get the tooltip location div
+ const tooltipLocationDiv = screen.getByTestId('msla-tooltip-location-test_id');
+
+ // Assert that the location div are rendered correctly
+ expect(tooltipLocationDiv).toBeInTheDocument();
+ expect(tooltipLocationDiv).toHaveStyle({ position: 'absolute', top: '100px', left: '100px' });
+ expect(baseElement).toMatchSnapshot();
+ });
+
+ it('should default to locationRef if targetRef is not provided', () => {
+ renderComponent();
+
+ const tooltipDiv = screen.getByRole('tooltip').parentElement;
+ expect(tooltipDiv).toHaveStyle({ position: 'absolute', top: '0px', left: '0px' });
+ });
+});
diff --git a/libs/designer/src/lib/ui/common/DesignerContextualMenu/__test__/__snapshots__/CopyTooltip.spec.tsx.snap b/libs/designer/src/lib/ui/common/DesignerContextualMenu/__test__/__snapshots__/CopyTooltip.spec.tsx.snap
new file mode 100644
index 00000000000..ba540f376e5
--- /dev/null
+++ b/libs/designer/src/lib/ui/common/DesignerContextualMenu/__test__/__snapshots__/CopyTooltip.spec.tsx.snap
@@ -0,0 +1,67 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`CopyTooltip > should position the tooltip based on the provided location 1`] = `
+
+
+
+
+
+`;
+
+exports[`CopyTooltip > should render the tooltip with the correct content 1`] = `
+
+
+
+
+
+`;