Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions content/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
/en/dd_e2e/cdocs/integration/content_filtering.md
/en/dd_e2e/cdocs/integration/headings_and_toc.md
/en/dd_e2e/cdocs/integration/sticky_data.md
/en/agent/tooltip_test.md
/en/dd_e2e/cdocs/integration/conditionally_displayed_filters/hide_if.md
/en/dd_e2e/cdocs/integration/conditionally_displayed_filters/show_if.md
/en/dd_e2e/cdocs/integration/dynamic_options.md
/en/dd_e2e/cdocs/components/glossary_tooltip.md
20 changes: 20 additions & 0 deletions content/en/dd_e2e/cdocs/components/glossary_tooltip.mdoc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
title: Glossary tooltip
draft: true
---

## Case tests

Default case: {% glossary-tooltip term="new" /%}

Title case: {% glossary-tooltip term="new" case="title" /%}
Comment thread
hestonhoffman marked this conversation as resolved.
Outdated

Title case (no short definition): {% glossary-tooltip term="snmp" case="title" /%}

Sentence case: {% glossary-tooltip term="new" case="sentence" /%}

Sentence case (no short definition): {% glossary-tooltip term="snmp" case="sentence" /%}

Lower case: {% glossary-tooltip term="new" case="lower" /%}

Upper case: {% glossary-tooltip term="new" case="upper" /%}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
---
id: extract_etl
title: extract, transform, and load (ETL)
related_terms:
---
An established system where you pull data, transform the data, and load the output into a data warehouse. For more information, <a href="https://www.datadoghq.com/blog/engineering/crunchconf-talk-self-serve-analytics/#data-as-a-product-the-single-source-of-truth">see the blog post</a>.
1 change: 0 additions & 1 deletion content/es/glossary/terms/extract_(ETL).md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
---
id: extract_etl
related_terms: null
title: extracción, transformación y carga (ETL)
---
Un sistema establecido en el que se extraen datos, se transforman y se carga el resultado en un almacén de datos. Para obtener más información, <a href="https://www.datadoghq.com/blog/engineering/crunchconf-talk-self-serve-analytics/#data-as-a-product-the-single-source-of-truth">consulta la entrada del blog</a>.
1 change: 0 additions & 1 deletion content/fr/glossary/terms/extract_(ETL).md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
---
id: extract_etl
related_terms: null
title: extract, transform, and load (ETL)
---
Un système établi dans lequel vous récupérez des données, les transformez et chargez le résultat dans un entrepôt de données. Pour plus d'informations, <a href="https://www.datadoghq.com/blog/engineering/crunchconf-talk-self-serve-analytics/#data-as-a-product-the-single-source-of-truth">consultez l'article de blog à ce sujet</a>.
1 change: 0 additions & 1 deletion content/ja/glossary/terms/extract_(ETL).md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
---
id: extract_etl
related_terms: null
title: 抽出、変換、書き出し (ETL)
---
データを抽出し、変換し、その結果をデータウェアハウスにロードする確立されたシステム。詳しくは、<a href="https://www.datadoghq.com/blog/engineering/crunchconf-talk-self-serve-analytics/#data-as-a-product-the-single-source-of-truth">ブログ記事を参照</a>してください。
76 changes: 76 additions & 0 deletions e2e/components/glossary-tooltip/cdocs-glossary-tooltip.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { test, expect, type Page, type Locator } from '@playwright/test';
import { hideOverlays } from '../../helpers';

const PAGE_URL = '/dd_e2e/cdocs/components/glossary_tooltip/';
const CONTENT_AREA = '#mainContent';

function paragraph(page: Page, label: string): Locator {
return page.locator('p', { hasText: label });
}

test.describe('Cdocs glossary-tooltip component', () => {
test.beforeEach(async ({ page }) => {
await page.goto(PAGE_URL);
await page.waitForSelector(CONTENT_AREA);
await hideOverlays(page);
});

test('page renders as expected', async ({ page }) => {
await expect(page.locator(CONTENT_AREA)).toHaveScreenshot('glossary-tooltip-initial.png');
});

test('default case renders glossary title unchanged', async ({ page }) => {
const trigger = paragraph(page, 'Default case:').locator('.tooltip-trigger');
await expect(trigger).toHaveText('new');
});

test('casing is applied to the tooltip trigger text', async ({ page }) => {
const expected: [string, string][] = [
['Title case:', 'New'],
['Sentence case:', 'New'],
['Lower case:', 'new'],
['Upper case:', 'NEW']
];

for (const [label, text] of expected) {
const trigger = paragraph(page, label).locator('.tooltip-trigger');
await expect(trigger).toHaveText(text);
}
});

test('no-short-definition renders title as plain text, no tooltip wrapper', async ({ page }) => {
const expected: [string, string][] = [
['Title case (no short definition):', 'Simple Network Management Protocol (snmp)'],
['Sentence case (no short definition):', 'Simple network management protocol (snmp)']
];

for (const [label, text] of expected) {
const para = paragraph(page, label);
await expect(para).toContainText(text);
await expect(para.locator('.tooltip-container')).toHaveCount(0);
}
});

test('hover reveals the tooltip popup with the short definition', async ({ page }) => {
const trigger = paragraph(page, 'Default case:').locator('.tooltip-trigger');

await trigger.hover();
// tooltip.js lifts the popup to <body> on hover (escapes ancestor overflow:hidden).
const popup = page.locator('body > .tooltip-content.show');
await expect(popup).toBeVisible();
await expect(popup).toContainText('NEW indicates a fully developed');
});

test('tooltip contains a working link to the glossary entry', async ({ page }) => {
const para = paragraph(page, 'Default case:');
const link = para.locator('a.tooltip-full-link');

await expect(link).toHaveAttribute('href', /\/glossary\/#new$/);
await expect(link).toHaveText('Glossary');

await para.locator('.tooltip-trigger').hover();
await page.locator('body > .tooltip-content.show a.tooltip-full-link').click();
await expect(page).toHaveURL(/\/glossary\/#new$/);
});

});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
116 changes: 116 additions & 0 deletions e2e/plans/glossary-tooltip.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# Glossary tooltip test prompt

Turn the mdoc at `content/en/agent/tooltip_test.mdoc.md` into a playwright test.

Move the page to the relevant directory, creating the relevant subdirectories if necessary.

The page should test the glossary tooltip for each scenario in the mdoc file:

- "Default case" should not apply casing to the title. The glossary tooltip should show on hover.
- "Title case" should apply casing to the title. The glossary tooltip should show on hover.
- "Title case (no short definition)" should apply title casing to the title. The glossary tooltip should not render.
- "Sentence case" should apply sentence casing to the title. The glossary tooltip should show on hover.
- "Sentence case (no short definition)" should apply sentence casing to the title. The glossary tooltip should not render.
- "Lower case" should apply lower casing to the title. The glossary tooltip should show on hover.
- "Upper case" should apply upper casing to the title. The glossary tooltip should show on hover.
- For the fallback option, the glossary tooltip should not render and the display text should match the tooltip ID.
- Also test the glossary tooltip. It should include a working link to the glossary entry.

When you're finished, run the tests to verify that they're passing
and that the snapshots are stable.

## Plan

### Context

The `glossary-tooltip` Markdoc tag was added in `cdocs-hugo-integration@2.17.0` (branch `heston/cdocs-glossary`, commit `a0dda411dc`). A draft mdoc test page exists at `content/en/agent/tooltip_test.mdoc.md` but it isn't wired into Playwright. This plan moves that page under the e2e content tree and adds a Playwright spec that exercises each casing scenario and verifies the tooltip popup + glossary link.

#### Scenarios actually exercised (after clarifications)

The tag's behavior, per `node_modules/cdocs-hugo-integration/dist/markdocCustomization/tags/glossaryTooltip.js`:
- Term found + `short_definition` present → full tooltip (button + popup + glossary link), with casing applied.
- Term found + no `short_definition` → renders the glossary `title` as plain text (no tooltip wrapper), with casing applied.
- Term not found + `lang === "en"` → **throws at Markdoc compile time**. This path is unreachable from an English e2e page, so we are not covering it in this PR (per user decision).

The original prompt's "fallback … display text should match the tooltip ID" description doesn't match the code: when no `short_definition` exists, the rendered text is the glossary `title`, which only equals the ID by coincidence for `anomaly` (title: `anomaly`) and differs for `snmp` (title: `Simple Network Management Protocol (SNMP)`). The spec asserts against the actual title.

### Steps

#### 1. Move the test page

Move (via `git mv`) and rename for consistency with existing cdocs e2e pages:

- `content/en/agent/tooltip_test.mdoc.md` → `content/en/dd_e2e/cdocs/components/glossary_tooltip.mdoc.md`

Update the frontmatter title from `Glossary tooltip Test Page` to `Glossary tooltip`. Leave `draft: true`. Drop the stale "I made this page before we introduced Playwright" note.

The mdoc content stays byte-identical otherwise — every existing line maps to a test assertion below. No new scenarios are added.

Resulting URL: `/dd_e2e/cdocs/components/glossary_tooltip/`.

The `.md` compiled sibling is generated by `make build-cdocs` and is checked in (repo convention — see `content/en/dd_e2e/cdocs/components/tooltip.md`).

#### 2. Add the Playwright spec

Create `e2e/components/glossary-tooltip/cdocs-glossary-tooltip.spec.ts`.

Pattern-match on `e2e/components/tabs/cdocs-tabs.spec.ts` (snapshot + targeted assertions) rather than the minimal `cdocs-tooltip.spec.ts` — casing and hover behavior warrant DOM-level checks, not just a snapshot.

Imports and setup mirror `cdocs-tooltip.spec.ts` (goto, wait for `#mainContent`, `hideOverlays`).

Tests (keep small and focused — one behavior per test):

1. **Initial page snapshot** — `await expect(page.locator('#mainContent')).toHaveScreenshot('glossary-tooltip-initial.png')`. Covers all casing + no-short-def layouts in one image.
2. **Default case renders glossary title verbatim** — assert the button inside the "Default case:" paragraph has text `new` (matches `content/en/glossary/terms/new.md` title).
3. **Casing is applied to the button text** — for each of `title`, `sentence`, `lower`, `upper`, find the corresponding `.tooltip-trigger` and assert its text:
- title: `New`
- sentence: `New`
- lower: `new`
- upper: `NEW`
4. **No-short-definition renders title as plain text, no tooltip container** — in the "Title case (no short definition)" and "Sentence case (no short definition)" paragraphs, assert:
- No `.tooltip-container` descendant.
- Visible text matches the SNMP title with casing applied:
- title case: `Simple Network Management Protocol (snmp)` — `toTitleCase` lowercases first, then capitalizes the first character of each space-split word. `(SNMP)` becomes `(snmp)` because the `(` is the first char and `s` stays lowercase.
- sentence case: `Simple network management protocol (snmp)`
5. **Hover shows the tooltip popup** — hover over the default-case `.tooltip-trigger`. `tooltip.js` moves the popup to `<body>` on hover (to escape ancestor `overflow: hidden`), so assert against `body > .tooltip-content.show` — a paragraph-scoped locator stops working after hover. Verify it contains the `short_definition` text from `new.md`.
6. **Tooltip contains a working glossary link** — assert `a.tooltip-full-link` has an href ending in `/glossary/#new` (Hugo rewrites to absolute URLs at serve time, so use a regex tail-match rather than exact string) and text `Glossary`. Hover, click the link, and assert `page.url()` ends with `/glossary/#new`.

Locators: use paragraph-scoped queries (e.g., `page.locator('p', { hasText: 'Default case:' })`) to keep tests resilient to ordering changes. Do NOT use `nth()`.

#### 3. Generate snapshots and run

```bash
npx playwright test e2e/components/glossary-tooltip --update-snapshots
npx playwright test e2e/components/glossary-tooltip
npx playwright test e2e/components/glossary-tooltip # second run to confirm stability
```

Requires `yarn start` (or `yarn run start` if cdocs is already compiled) running on `localhost:1313`.

### Files to create / modify

- **Move**: `content/en/agent/tooltip_test.mdoc.md` → `content/en/dd_e2e/cdocs/components/glossary_tooltip.mdoc.md` (via `git mv`, then edit frontmatter).
- **Regenerate**: `content/en/dd_e2e/cdocs/components/glossary_tooltip.md` (auto-produced by `make build-cdocs`; commit it).
- **Create**: `e2e/components/glossary-tooltip/cdocs-glossary-tooltip.spec.ts`.
- **Create**: `e2e/components/glossary-tooltip/cdocs-glossary-tooltip.spec.ts-snapshots/glossary-tooltip-initial-chromium-darwin.png` (generated).

### Reused code / references

- `e2e/helpers.ts` — `hideOverlays` for stable snapshots.
- `e2e/components/tabs/cdocs-tabs.spec.ts` — structural template.
- `assets/scripts/components/tooltip.js` — shows that `showTooltip` appends the popup to `document.body`.
- `node_modules/cdocs-hugo-integration/dist/markdocCustomization/tags/glossaryTooltip.js` — source of truth for behavior the assertions mirror.
- `node_modules/cdocs-hugo-integration/dist/markdocCustomization/utils/formatStrings.js` — `toTitleCase` / `toSentenceCase` implementations.
- `content/en/glossary/terms/{new,snmp,anomaly}.md` — fixture data the assertions depend on.

### Verification

1. `make build-cdocs` completes without errors (confirms the mdoc compiles and no "term not found" throw).
2. `yarn start` serves the page at `/dd_e2e/cdocs/components/glossary_tooltip/`; visually check hover behavior in a browser.
3. `npx playwright test e2e/components/glossary-tooltip` passes.
4. Re-run the same command — all assertions still pass and no snapshot diff surfaces.

### Caveats / follow-ups

- **Not-found path uncovered.** English throws at compile; the `return term` branch in `glossaryTooltip.js` is only reachable for non-English pages. If coverage matters, either relax the English throw in the cdocs tag or add a parallel non-English test page — neither is in scope here.
- **Casing on SNMP looks wrong.** `toTitleCase` turns `Simple Network Management Protocol (SNMP)` into `Simple Network Management Protocol (snmp)` — it loses the caps on `SNMP` entirely. The spec asserts the actual output, but this is worth flagging to whoever owns the tag — it may be a latent bug.
Copy link
Copy Markdown
Contributor Author

@hestonhoffman hestonhoffman Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: I noticed this in testing and decided not to fix it. Realistically, I doubt it will come up much. Most of the time with abbreviations like this, sentence case will already be baked in to the glossary term title. It's also the way this already works in prod, so no major loss there.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
"@popperjs/core": "^2.11.8",
"alpinejs": "^3.13.7",
"bootstrap": "^5.2",
"cdocs-hugo-integration": "https://s3.amazonaws.com/origin-static-assets/corp-node-packages/master/cdocs-hugo-integration-v2.16.0.tgz",
"cdocs-hugo-integration": "https://s3.amazonaws.com/origin-static-assets/corp-node-packages/master/cdocs-hugo-integration-v2.17.0.tgz",
"del": "4.1.1",
"fancy-log": "^1.3.3",
"geo-locate": "https://s3.amazonaws.com/origin-static-assets/corp-node-packages/master/geo-locate-v1.0.2.tgz",
Expand Down
10 changes: 5 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6647,9 +6647,9 @@ __metadata:
languageName: node
linkType: hard

"cdocs-hugo-integration@https://s3.amazonaws.com/origin-static-assets/corp-node-packages/master/cdocs-hugo-integration-v2.16.0.tgz":
version: 2.16.0
resolution: "cdocs-hugo-integration@https://s3.amazonaws.com/origin-static-assets/corp-node-packages/master/cdocs-hugo-integration-v2.16.0.tgz"
"cdocs-hugo-integration@https://s3.amazonaws.com/origin-static-assets/corp-node-packages/master/cdocs-hugo-integration-v2.17.0.tgz":
version: 2.17.0
resolution: "cdocs-hugo-integration@https://s3.amazonaws.com/origin-static-assets/corp-node-packages/master/cdocs-hugo-integration-v2.17.0.tgz"
dependencies:
"@prettier/sync": "npm:^0.5.2"
"@types/markdown-it": "npm:^14.1.2"
Expand All @@ -6674,7 +6674,7 @@ __metadata:
vite: "npm:^5.4.10"
vite-plugin-singlefile: "npm:^2.0.2"
zod: "npm:^4.1.12"
checksum: 10/7ff9efbc77a5911c02c305d624e5adb5ba9fe1c5dff8cfccec6e133755eefeb1a75e626e82cf0608100dc50d71196013db935a680536807977ee2007a3a54ffb
checksum: 10/d0dd0cc4b13cb48e6f51eed21063c335d1a67fd99eb3ec6bcc26b193726bf6bdfb94ba85f946c3f66a524f18172f1f619583c6a69ce6d7f34b03c2f1c7446cc1
languageName: node
linkType: hard

Expand Down Expand Up @@ -7725,7 +7725,7 @@ __metadata:
acorn: "npm:^7.4.1"
alpinejs: "npm:^3.13.7"
bootstrap: "npm:^5.2"
cdocs-hugo-integration: "https://s3.amazonaws.com/origin-static-assets/corp-node-packages/master/cdocs-hugo-integration-v2.16.0.tgz"
cdocs-hugo-integration: "https://s3.amazonaws.com/origin-static-assets/corp-node-packages/master/cdocs-hugo-integration-v2.17.0.tgz"
cross-env: "npm:^5.2.1"
del: "npm:4.1.1"
eslint: "npm:^6.8.0"
Expand Down
Loading