diff --git a/clients/web/src/components/groups/ConnectionInfoContent/ConnectionInfoContent.test.tsx b/clients/web/src/components/groups/ConnectionInfoContent/ConnectionInfoContent.test.tsx
index 53b225e1..1a525839 100644
--- a/clients/web/src/components/groups/ConnectionInfoContent/ConnectionInfoContent.test.tsx
+++ b/clients/web/src/components/groups/ConnectionInfoContent/ConnectionInfoContent.test.tsx
@@ -625,6 +625,57 @@ describe("ConnectionInfoContent", () => {
}
});
+ it("groups the full-width fields at the end, Client ID directly above Access Token", () => {
+ renderWithMantine(
+ ,
+ );
+
+ // Order is the assertion, so read the labels off the DOM rather than
+ // checking each is merely present: the inline two-column rows come first,
+ // then every label-over-value field together. Interleaving them is what
+ // this guards against — it broke the scan down the label column, and the
+ // tokens already used the full-width layout at the bottom.
+ const order = [
+ "Client registration",
+ "Scopes",
+ "Auth URL",
+ "Client ID",
+ "Access Token",
+ ];
+ const positions = order.map((label) => {
+ const node = screen.getAllByText(label)[0];
+ expect(node).toBeInTheDocument();
+ return (
+ node.compareDocumentPosition(screen.getAllByText("Protocol")[0]) &
+ Node.DOCUMENT_POSITION_PRECEDING
+ );
+ });
+ expect(positions.every(Boolean)).toBe(true);
+
+ const labelNode = (label: string) => screen.getAllByText(label)[0];
+ for (let i = 0; i < order.length - 1; i++) {
+ const earlier = labelNode(order[i]);
+ const later = labelNode(order[i + 1]);
+ expect(
+ earlier.compareDocumentPosition(later) &
+ Node.DOCUMENT_POSITION_FOLLOWING,
+ ).toBeTruthy();
+ }
+ });
+
it("renders EMA idp session when provided", () => {
renderWithMantine(
- {oauth.clientId && (
-
- Client ID
- {oauth.clientId}
-
- )}
{oauth.clientRegistrationKind && (
Client registration
@@ -479,17 +473,29 @@ export function ConnectionInfoContent({
{formatIdpSession(oauth.idpSession)}
)}
+ {oauth.scopes && oauth.scopes.length > 0 && (
+
+ Scopes
+ {formatScopes(oauth.scopes)}
+
+ )}
+ {/* The full-width fields are kept together at the end of the
+ section, directly above the token rows, which use the same
+ label-over-value layout. Interleaved with the inline two-column
+ rows they broke the scan down the label column for every row
+ after them, and Client ID — the one most likely to be long —
+ was the worst offender (#2328). */}
{oauth.authUrl && (
Auth URL
{oauth.authUrl}
)}
- {oauth.scopes && oauth.scopes.length > 0 && (
-
- Scopes
- {formatScopes(oauth.scopes)}
-
+ {oauth.clientId && (
+
+ Client ID
+ {oauth.clientId}
+
)}
{oauth.accessToken && (