]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-18892 Fix leading stacked location in source viewer
authorMathieu Suen <mathieu.suen@sonarsource.com>
Tue, 28 Mar 2023 12:13:11 +0000 (14:13 +0200)
committersonartech <sonartech@sonarsource.com>
Thu, 30 Mar 2023 20:03:07 +0000 (20:03 +0000)
server/sonar-web/src/main/js/apps/permission-templates/components/__tests__/__snapshots__/PermissionTemplatesApp-it.tsx.snap
server/sonar-web/src/main/js/components/common/DocumentationTooltip.tsx
server/sonar-web/src/main/js/components/common/LocationIndex.css
server/sonar-web/src/main/js/components/common/__tests__/DocumentationTooltip-test.tsx
server/sonar-web/src/main/js/components/controls/Tooltip.tsx
server/sonar-web/src/main/js/components/controls/__tests__/Tooltip-test.tsx
server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/Tooltip-test.tsx.snap

index eebb77c2e35823a8d080114d690ae68186d8e806..e05b7037600234022dc99ef4c047a1c1bead14da 100644 (file)
@@ -14,7 +14,7 @@ exports[`rendering should render the list of templates: Permission Template 1: u
 
 exports[`rendering should render the list of templates: Permission Template 2: admin 1`] = `"0  user(s)0 group(s)"`;
 
-exports[`rendering should render the list of templates: Permission Template 2: codeviewer 1`] = `"permission_templates.project_creatorspermission_templates.project_creators.explanationpermission_templates.project_creators.explanation0  user(s)0 group(s)"`;
+exports[`rendering should render the list of templates: Permission Template 2: codeviewer 1`] = `"permission_templates.project_creatorspermission_templates.project_creators.explanation0  user(s)0 group(s)"`;
 
 exports[`rendering should render the list of templates: Permission Template 2: issueadmin 1`] = `"0  user(s)0 group(s)"`;
 
@@ -22,4 +22,4 @@ exports[`rendering should render the list of templates: Permission Template 2: s
 
 exports[`rendering should render the list of templates: Permission Template 2: securityhotspotadmin 1`] = `"0  user(s)0 group(s)"`;
 
-exports[`rendering should render the list of templates: Permission Template 2: user 1`] = `"permission_templates.project_creatorspermission_templates.project_creators.explanationpermission_templates.project_creators.explanation0  user(s)0 group(s)"`;
+exports[`rendering should render the list of templates: Permission Template 2: user 1`] = `"permission_templates.project_creatorspermission_templates.project_creators.explanation0  user(s)0 group(s)"`;
index cd75a88aa404f60b421c3d4d001d2b54b2319863..3bbde1f91da6c6bd8e8303d1fff39d4cbbcc2865 100644 (file)
@@ -56,6 +56,7 @@ export default function DocumentationTooltip(props: DocumentationTooltipProps) {
         return;
       }
       if (event.target === last(linksRef.current)) {
+        event.preventDefault();
         nextSelectableNode.current?.focus();
         return;
       }
index 74619a1f5238a73745a6bcc100c7b4172d0d339f..c587a86ecd72808a184ecbc65b40d992b04efc10 100644 (file)
   margin-left: 0;
 }
 
-.location-index.is-leading:not(:first-child) {
-  margin-left: -22px;
-}
-
 .location-index[tabindex] {
   cursor: pointer;
 }
index cfb21c7bf121acf5bb956e6acc735ecd64f887a8..197fd1c97b468355fcfbae3d66bb2df9f998f617 100644 (file)
@@ -29,6 +29,7 @@ const ui = {
   body: byRole('body'),
   beforeLink: byRole('link', { name: 'Interactive element before' }),
   helpIcon: byTestId('help-tooltip-activator'),
+  helpLink: byRole('link', { name: 'Icon' }),
   linkInTooltip: byRole('link', { name: 'Label' }),
   linkInTooltip2: byRole('link', { name: 'opens_in_new_window Label2' }),
   afterLink: byRole('link', { name: 'Interactive element after' }),
@@ -43,19 +44,19 @@ it('should correctly navigate through TAB', async () => {
   await user.tab();
   expect(ui.helpIcon.get()).toHaveFocus();
   await user.tab();
-  expect(ui.linkInTooltip.getAll().at(1)).toHaveFocus();
+  expect(ui.linkInTooltip.get()).toHaveFocus();
   await user.tab();
-  expect(ui.linkInTooltip2.getAll().at(1)).toHaveFocus();
+  expect(ui.linkInTooltip2.get()).toHaveFocus();
   // Looks like RTL tab event ignores any custom focuses during the events phase,
   // unless preventDefault is specified
   await user.tab();
+  expect(ui.helpIcon.get()).toHaveFocus();
   await user.tab({ shift: true });
-  expect(await ui.afterLink.find()).toHaveFocus();
   await user.tab({ shift: true });
   await user.tab();
   await user.tab();
   await user.tab({ shift: true });
-  expect(await ui.afterLink.find()).toHaveFocus();
+  expect(await ui.beforeLink.find()).toHaveFocus();
 });
 
 function renderDocumentationTooltip(props: Partial<DocumentationTooltipProps> = {}) {
@@ -81,7 +82,11 @@ function renderDocumentationTooltip(props: Partial<DocumentationTooltipProps> =
           },
         ]}
         {...props}
-      />
+      >
+        <Link to="/" target="_blank">
+          Icon
+        </Link>
+      </DocumentationTooltip>
       <Link to="/" target="_blank">
         Interactive element after
       </Link>
index 0aeaad34b4157cb81e7363361442fee5156e86af..eeff7ebe1a7c7a197d7e8fbdf68de3b9bc29a947 100644 (file)
@@ -430,7 +430,7 @@ export class TooltipInner extends React.Component<TooltipProps, State> {
           // can mess up buttons that need a tooltip).
           'aria-describedby': this.id,
         })}
-        {!isVisible && this.renderOverlay()}
+        {!isVisible && <TooltipPortal>{this.renderOverlay()}</TooltipPortal>}
         {isVisible && (
           <EscKeydownHandler onKeydown={this.closeTooltip}>
             <TooltipPortal>
index 97004fe4117352ef5dcc20460b263142c0c55523..d8d5347a7099628fe9f6ae267b1b4d3d6eb41ce5 100644 (file)
@@ -66,40 +66,23 @@ it('should open & close', () => {
   wrapper.find('#tooltip').simulate('pointerenter');
   jest.runOnlyPendingTimers();
   wrapper.update();
-  expect(wrapper.find('TooltipPortal').exists()).toBe(true);
   expect(onShow).toHaveBeenCalled();
 
   wrapper.find('#tooltip').simulate('pointerleave');
   jest.runOnlyPendingTimers();
   wrapper.update();
-  expect(wrapper.find('TooltipPortal').exists()).toBe(false);
   expect(onHide).toHaveBeenCalled();
 
   onShow.mockReset();
   onHide.mockReset();
 
   wrapper.find('#tooltip').simulate('focus');
-  expect(wrapper.find('TooltipPortal').exists()).toBe(true);
   expect(onShow).toHaveBeenCalled();
 
   wrapper.find('#tooltip').simulate('blur');
-  expect(wrapper.find('TooltipPortal').exists()).toBe(false);
   expect(onHide).toHaveBeenCalled();
 });
 
-it('should not open when pointer goes away quickly', () => {
-  const onShow = jest.fn();
-  const onHide = jest.fn();
-  const wrapper = shallowRenderTooltipInner({ onHide, onShow });
-
-  wrapper.find('#tooltip').simulate('pointerenter');
-  wrapper.find('#tooltip').simulate('pointerleave');
-  jest.runOnlyPendingTimers();
-  wrapper.update();
-
-  expect(wrapper.find('TooltipPortal').exists()).toBe(false);
-});
-
 it('should not render tooltip without overlay', () => {
   const wrapper = shallowRenderTooltip();
   expect(wrapper.type()).toBe('div');
index ce84e743745b6431c1b9fe9a5734cfc91770042a..6cbc3a5b5c8e36eb59574052bf4f14a2440b70ed 100644 (file)
@@ -22,16 +22,18 @@ exports[`should render 1`] = `
     onPointerEnter={[Function]}
     onPointerLeave={[Function]}
   />
-  <div
-    aria-hidden={true}
-    className="tooltip-inner sw-font-sans hidden"
-    id="tooltip-1"
-    role="tooltip"
-  >
-    <span
-      id="overlay"
-    />
-  </div>
+  <TooltipPortal>
+    <div
+      aria-hidden={true}
+      className="tooltip-inner sw-font-sans hidden"
+      id="tooltip-1"
+      role="tooltip"
+    >
+      <span
+        id="overlay"
+      />
+    </div>
+  </TooltipPortal>
 </Fragment>
 `;