diff --git a/tests/Elastic.Markdown.Tests/.snapshots/Directives/AdmonitionAppliesToTests/RendersHtml.verified.html b/tests/Elastic.Markdown.Tests/.snapshots/Directives/AdmonitionAppliesToTests/RendersHtml.verified.html new file mode 100644 index 0000000000..c6be56cf00 --- /dev/null +++ b/tests/Elastic.Markdown.Tests/.snapshots/Directives/AdmonitionAppliesToTests/RendersHtml.verified.html @@ -0,0 +1,13 @@ +
This is a custom admonition with applies_to information
+A regular paragraph.
diff --git a/tests/Elastic.Markdown.Tests/.snapshots/Directives/AgentSkillNoSkillNameTests/RendersHtml.verified.html b/tests/Elastic.Markdown.Tests/.snapshots/Directives/AgentSkillNoSkillNameTests/RendersHtml.verified.html new file mode 100644 index 0000000000..bdb7a52031 --- /dev/null +++ b/tests/Elastic.Markdown.Tests/.snapshots/Directives/AgentSkillNoSkillNameTests/RendersHtml.verified.html @@ -0,0 +1,23 @@ +A skill is available to help AI agents with this topic.
+ +A regular paragraph.
diff --git a/tests/Elastic.Markdown.Tests/.snapshots/Directives/AgentSkillTests/RendersHtml.verified.html b/tests/Elastic.Markdown.Tests/.snapshots/Directives/AgentSkillTests/RendersHtml.verified.html new file mode 100644 index 0000000000..ec0c0fe6af --- /dev/null +++ b/tests/Elastic.Markdown.Tests/.snapshots/Directives/AgentSkillTests/RendersHtml.verified.html @@ -0,0 +1,23 @@ +A skill is available to help AI agents with this topic.
+ +A regular paragraph.
diff --git a/tests/Elastic.Markdown.Tests/.snapshots/Directives/AgentSkillWithBodyTests/RendersHtml.verified.html b/tests/Elastic.Markdown.Tests/.snapshots/Directives/AgentSkillWithBodyTests/RendersHtml.verified.html new file mode 100644 index 0000000000..688457a4e6 --- /dev/null +++ b/tests/Elastic.Markdown.Tests/.snapshots/Directives/AgentSkillWithBodyTests/RendersHtml.verified.html @@ -0,0 +1,24 @@ +A skill is available to help AI agents with this topic.
+This skill helps agents write and optimize ES|QL queries.
+ +A regular paragraph.
diff --git a/tests/Elastic.Markdown.Tests/.snapshots/Directives/ApplicabilitySwitchTests/RendersHtml.verified.html b/tests/Elastic.Markdown.Tests/.snapshots/Directives/ApplicabilitySwitchTests/RendersHtml.verified.html new file mode 100644 index 0000000000..425255841a --- /dev/null +++ b/tests/Elastic.Markdown.Tests/.snapshots/Directives/ApplicabilitySwitchTests/RendersHtml.verified.html @@ -0,0 +1,50 @@ +This feature is in preview for Elastic Stack 9.1.
+This feature is available for Elastic Cloud.
+This feature has been removed from Elastic Cloud Enterprise.
+Content A
+Content B
+Known issue. + #333333 +
++ Impact: + Some users may be affected.
+Deprecation notice. + #222222 +
++ Impact: + Users should migrate.
++ Action: + Use the new API.
+Deprecation in Search. + #222222 +
++ Impact: + None.
++ Action: + Upgrade.
+Deprecation notice. + #222222 +
++ Impact: + None.
++ Action: + Upgrade.
+Blocked entry. + #22222 +
++ Impact: + None.
++ Action: + Upgrade.
++ Indexing +
+Indexing deprecation. + #666666 +
++ Impact: + Will be removed.
++ Action: + Update config.
++ Search +
+Search deprecation. + #555555 +
++ Impact: + Will be removed.
++ Action: + Migrate to new API.
+Breaking API change. + #333333 + API has been changed to improve performance.
++ Impact: + Existing API calls will fail.
++ Action: + Update your code to use the new API endpoints.
+Another breaking change. + #444444 + Removed deprecated parameter.
++ Impact: + Scripts using the old parameter will fail.
++ Action: + Remove references to the deprecated parameter.
+API has been changed to improve performance.
+For more information, check + #333333.
+
+ Impact
+
Existing API calls will fail.
+ Action
+
Update your code to use the new API endpoints.
For more information, check + #333333.
+
+ Impact
+
Existing API calls will fail.
+ Action
+
Update your code to use the new API endpoints.
For more information, check + #222222.
+
+ Impact
+
Users must update.
+ Action
+
Follow guide.
For more information, check + #333333.
+
+ Impact
+
Search results incomplete.
+ Action
+
Use workaround.
The default value has a space instead of a plus sign.
+For more information, check + #242365.
+
+ Impact
+
Deployments fail.
+ Action
+
Update the template.
Breaking API change. + #222222 +
++ Impact: + Users must update.
++ Action: + Follow guide.
+Known issue with search. + #333333 +
++ Impact: + Search results incomplete.
++ Action: + Use workaround.
+Deprecated API. + #444444 +
++ Impact: + Will be removed in future.
++ Action: + Use new API.
+Breaking API change. + #444444 +
++ Impact: + Users must update.
++ Action: + Follow guide.
+Highlighted feature. + #111111 +
+This is the highlight description.
+Regular feature. + #222222 +
+Breaking API change. + #444444 +
++ Impact: + Users must update.
++ Action: + Follow guide.
++ Indexing +
++ Search +
+Breaking API change. + #333333 +
++ Impact: + Users must update.
++ Action: + Follow guide.
+Known issue. + #444444 +
++ Impact: + Some impact.
++ Action: + Workaround available.
+Deprecated feature. + #555555 +
++ Impact: + Will be removed.
++ Action: + Use new feature.
+Breaking change. + #222222 +
++ Impact: + Impact.
++ Action: + Action.
+Deprecated feature. + #555555 +
++ Impact: + Will be removed.
++ Action: + Use new feature.
+Another deprecation. + #666666 +
++ Impact: + Also will be removed.
++ Action: + Migrate to new API.
+Known issue 1. + #444444 +
++ Impact: + Some impact.
++ Action: + Workaround available.
+Known issue 2. + #555555 +
++ Impact: + Different impact.
++ Action: + Different workaround.
+Breaking change. + #333333 +
++ Impact: + Impact.
++ Action: + Action.
++ Indexing +
++ Search +
+Breaking change in API. + #222222 +
++ Impact: + Users must update their code.
++ Action: + Follow the migration guide.
+Deprecated old API. + #333333 +
++ Impact: + The API will be removed in a future version.
++ Action: + Use the new API instead.
+This dropdown contains nested content with colons:
+function test() { return "hello:world"; }
+ And even nested directives:
+This is a nested note with colons: 10:30 AM
+More content after nested directive.
+A regular paragraph.
diff --git a/tests/Elastic.Markdown.Tests/.snapshots/Directives/ExerciseDirectiveTest/EmitsUnsupportedWarnings.verified.txt b/tests/Elastic.Markdown.Tests/.snapshots/Directives/ExerciseDirectiveTest/EmitsUnsupportedWarnings.verified.txt new file mode 100644 index 0000000000..e0fd299fb6 --- /dev/null +++ b/tests/Elastic.Markdown.Tests/.snapshots/Directives/ExerciseDirectiveTest/EmitsUnsupportedWarnings.verified.txt @@ -0,0 +1 @@ +warning {repo}/docs/index.md:1 Directive block 'exercise' is unsupported. See https://github.com/elastic/docs-builder/issues/30 for more information. diff --git a/tests/Elastic.Markdown.Tests/.snapshots/Directives/FrameDirectiveTests/EmitsUnsupportedWarnings.verified.txt b/tests/Elastic.Markdown.Tests/.snapshots/Directives/FrameDirectiveTests/EmitsUnsupportedWarnings.verified.txt new file mode 100644 index 0000000000..5d2f16166c --- /dev/null +++ b/tests/Elastic.Markdown.Tests/.snapshots/Directives/FrameDirectiveTests/EmitsUnsupportedWarnings.verified.txt @@ -0,0 +1 @@ +warning {repo}/docs/index.md:1 Directive block 'iframe' is unsupported. See https://github.com/elastic/docs-builder/issues/14 for more information. diff --git a/tests/Elastic.Markdown.Tests/.snapshots/Directives/ImportantAppliesToTests/RendersHtml.verified.html b/tests/Elastic.Markdown.Tests/.snapshots/Directives/ImportantAppliesToTests/RendersHtml.verified.html new file mode 100644 index 0000000000..0b42684253 --- /dev/null +++ b/tests/Elastic.Markdown.Tests/.snapshots/Directives/ImportantAppliesToTests/RendersHtml.verified.html @@ -0,0 +1,13 @@ +This is an important notice with applies_to information
+A regular paragraph.
diff --git a/tests/Elastic.Markdown.Tests/.snapshots/Directives/MystDirectiveDirectiveTests/EmitsUnsupportedWarnings.verified.txt b/tests/Elastic.Markdown.Tests/.snapshots/Directives/MystDirectiveDirectiveTests/EmitsUnsupportedWarnings.verified.txt new file mode 100644 index 0000000000..3ce73c34dc --- /dev/null +++ b/tests/Elastic.Markdown.Tests/.snapshots/Directives/MystDirectiveDirectiveTests/EmitsUnsupportedWarnings.verified.txt @@ -0,0 +1 @@ +warning {repo}/docs/index.md:1 Directive block 'myst' is unsupported. See https://github.com/elastic/docs-builder/issues/22 for more information. diff --git a/tests/Elastic.Markdown.Tests/.snapshots/Directives/NoteAppliesToTests/RendersHtml.verified.html b/tests/Elastic.Markdown.Tests/.snapshots/Directives/NoteAppliesToTests/RendersHtml.verified.html new file mode 100644 index 0000000000..c7ff61d071 --- /dev/null +++ b/tests/Elastic.Markdown.Tests/.snapshots/Directives/NoteAppliesToTests/RendersHtml.verified.html @@ -0,0 +1,13 @@ +This is a note with applies_to information
+A regular paragraph.
diff --git a/tests/Elastic.Markdown.Tests/.snapshots/Directives/SolutionDirectiveTests/EmitsUnsupportedWarnings.verified.txt b/tests/Elastic.Markdown.Tests/.snapshots/Directives/SolutionDirectiveTests/EmitsUnsupportedWarnings.verified.txt new file mode 100644 index 0000000000..f9d85a108d --- /dev/null +++ b/tests/Elastic.Markdown.Tests/.snapshots/Directives/SolutionDirectiveTests/EmitsUnsupportedWarnings.verified.txt @@ -0,0 +1 @@ +warning {repo}/docs/index.md:1 Directive block 'solution' is unsupported. See https://github.com/elastic/docs-builder/issues/31 for more information. diff --git a/tests/Elastic.Markdown.Tests/.snapshots/Directives/StepperTocFalseKeepsInternalHeadingsTests/RendersHtml.verified.html b/tests/Elastic.Markdown.Tests/.snapshots/Directives/StepperTocFalseKeepsInternalHeadingsTests/RendersHtml.verified.html new file mode 100644 index 0000000000..ce7aa1031b --- /dev/null +++ b/tests/Elastic.Markdown.Tests/.snapshots/Directives/StepperTocFalseKeepsInternalHeadingsTests/RendersHtml.verified.html @@ -0,0 +1,20 @@ +| Term | +Description | +
|---|---|
| foo | +A thing | +
| head a | +head b | +
|---|---|
| a | +b | +
| head a | +head b | +
|---|---|
| a | +b | +
This is a tip with applies_to information
+A regular paragraph.
diff --git a/tests/Elastic.Markdown.Tests/.snapshots/Directives/TocTreeDirectiveTests/EmitsUnsupportedWarnings.verified.txt b/tests/Elastic.Markdown.Tests/.snapshots/Directives/TocTreeDirectiveTests/EmitsUnsupportedWarnings.verified.txt new file mode 100644 index 0000000000..f9d85a108d --- /dev/null +++ b/tests/Elastic.Markdown.Tests/.snapshots/Directives/TocTreeDirectiveTests/EmitsUnsupportedWarnings.verified.txt @@ -0,0 +1 @@ +warning {repo}/docs/index.md:1 Directive block 'solution' is unsupported. See https://github.com/elastic/docs-builder/issues/31 for more information. diff --git a/tests/Elastic.Markdown.Tests/.snapshots/Directives/TopicDirectiveTests/EmitsUnsupportedWarnings.verified.txt b/tests/Elastic.Markdown.Tests/.snapshots/Directives/TopicDirectiveTests/EmitsUnsupportedWarnings.verified.txt new file mode 100644 index 0000000000..d3f15bfc78 --- /dev/null +++ b/tests/Elastic.Markdown.Tests/.snapshots/Directives/TopicDirectiveTests/EmitsUnsupportedWarnings.verified.txt @@ -0,0 +1 @@ +warning {repo}/docs/index.md:1 Directive block 'topic' is unsupported. See https://github.com/elastic/docs-builder/issues/24 for more information. diff --git a/tests/Elastic.Markdown.Tests/.snapshots/Directives/WarningAppliesToTests/RendersHtml.verified.html b/tests/Elastic.Markdown.Tests/.snapshots/Directives/WarningAppliesToTests/RendersHtml.verified.html new file mode 100644 index 0000000000..7e3616f91b --- /dev/null +++ b/tests/Elastic.Markdown.Tests/.snapshots/Directives/WarningAppliesToTests/RendersHtml.verified.html @@ -0,0 +1,13 @@ +This is a warning with applies_to information
+A regular paragraph.
diff --git a/tests/Elastic.Markdown.Tests/Directives/AdmonitionTests.cs b/tests/Elastic.Markdown.Tests/Directives/AdmonitionTests.cs index d2e17e5c0a..b3998aeea6 100644 --- a/tests/Elastic.Markdown.Tests/Directives/AdmonitionTests.cs +++ b/tests/Elastic.Markdown.Tests/Directives/AdmonitionTests.cs @@ -3,7 +3,9 @@ // See the LICENSE file in the project root for more information using AwesomeAssertions; +using Elastic.Documentation.Testing; using Elastic.Markdown.Myst.Directives.Admonition; +using Nullean.Snapshots.Html; namespace Elastic.Markdown.Tests.Directives; @@ -120,11 +122,27 @@ Dropdown body content. public void StripsBackticksFromTitle() => Block!.Title.Should().Be("Deprecate elastic.apm settings"); [Test] - public void RendersPlainTextTitleInHtml() - { - Html.Should().Contain("Deprecate elastic.apm settings"); - Html.Should().NotContain("`elastic.apm`"); - } + public void RendersHtml() => + Html.Should().MatchInlineHtmlSnapshot( + html: DocsHtml.Body(), + expected: """ +Dropdown body content.
+Dropdown body content.
+Dropdown body content.
+Added missing banner-related Kibana settings to the settings allowlist.
+This PR introduces the following settings.
++ Released: April 9, 2026 +
++ Released: April 9, 2026 +
+This release includes tracing improvements and bug fixes.
+Feature keep.
+BODY_KEEP_VISIBILITY
+Breaking API change.");
- }
-
- [Test]
- public void ExplicitDropdownsIncludesDescriptionInDropdown() => Html.Should().Contain("API has been changed to improve performance.");
-
- [Test]
- public void ExplicitDropdownsIncludesImpactAndActionInDropdown()
- {
- Html.Should().Contain("Impact Breaking API change.
+ #333333
+
+ Impact:
+ Existing API calls will fail.
+ Action:
+ Update your code to use the new API endpoints. Breaking API change.");
-
- // Description should be hidden due to :description-visibility: hide-descriptions
- Html.Should().NotContain("This description should be hidden.");
-
- // Impact and Action should still be shown in dropdown format
- Html.Should().Contain("Impact Breaking API change.");
- Html.Should().NotContain(" Known issue with search.");
- }
+ public void RendersHtml() => Html.Should().MatchHtmlSnapshot(DocsHtml.Body());
}
///
+ Released: April 9, 2026
+ This release includes tracing improvements and bug fixes.
+ Search
+ Breaking API change.
+ #333333
+
+ Impact:
+ Users must update.
+ Action:
+ Follow guide. Known issue in 9.3.
+ #444444
+
+ Impact:
+ Some impact.
+ Action:
+ Workaround available. This release was pulled due to critical issues.
Existing API calls will fail.");
- Html.Should().Contain("Action
Update your code to use the new API endpoints.");
- }
+ public void RendersHtml() => Html.Should().MatchHtmlSnapshot(DocsHtml.Body());
}
///
@@ -197,19 +153,30 @@ public ChangelogDropdownsWithHiddenDescriptionsTests() : base(
);
[Test]
- public void FlattendRenderingHidesDescriptionsButKeepsImpactAction()
- {
- // Should render as flattened (no dropdowns by default)
- Html.Should().Contain("Breaking API change.");
- Html.Should().NotContain("
+ 9.3.0
+
+
+
+ """
+ );
}
///
@@ -252,20 +219,7 @@ public ChangelogDropdownsEnabledWithHiddenDescriptionsTests() : base(
);
[Test]
- public void DropdownRenderingHidesDescriptionsButKeepsImpactAction()
- {
- // Should render as dropdown due to explicit :dropdowns:
- Html.Should().Contain("
Existing API calls will fail.");
- Html.Should().Contain("Action
Update your code to use the new API endpoints.");
- }
+ public void RendersHtml() => Html.Should().MatchHtmlSnapshot(DocsHtml.Body());
}
///
@@ -334,19 +288,7 @@ public ChangelogDropdownsWithDifferentTypesTests() : base(
);
[Test]
- public void DefaultRendersMixedTypesCorrectly()
- {
- // Regular types should render as bulleted lists (unchanged behavior)
- Html.Should().Contain("Feature addition."); // Regular feature type (in
@@ -406,20 +348,7 @@ public ChangelogDropdownsExplicitWithDifferentTypesTests() : base(
);
[Test]
- public void ExplicitDropdownsRendersMixedTypesCorrectly()
- {
- // Regular types should still render as bulleted lists (unchanged behavior)
- Html.Should().Contain("Feature addition."); // Regular feature type (in
@@ -462,9 +391,5 @@ public ChangelogDropdownsPlainTextTitleTests() : base(
);
[Test]
- public void ChangelogDropdownTitleStripsBackticksInHtml()
- {
- Html.Should().Contain("The ElasticAgentVersion parameter is malformed.");
- Html.Should().NotContain("`ElasticAgentVersion`");
- }
+ public void RendersHtml() => Html.Should().MatchHtmlSnapshot(DocsHtml.Body());
}
diff --git a/tests/Elastic.Markdown.Tests/Directives/ChangelogFlattenedLinksTests.cs b/tests/Elastic.Markdown.Tests/Directives/ChangelogFlattenedLinksTests.cs
index 66268fe47c..664c06f732 100644
--- a/tests/Elastic.Markdown.Tests/Directives/ChangelogFlattenedLinksTests.cs
+++ b/tests/Elastic.Markdown.Tests/Directives/ChangelogFlattenedLinksTests.cs
@@ -4,7 +4,9 @@
using System.IO.Abstractions.TestingHelpers;
using AwesomeAssertions;
+using Elastic.Documentation.Testing;
using Elastic.Markdown.Myst.Directives.Changelog;
+using Nullean.Snapshots.Html;
namespace Elastic.Markdown.Tests.Directives;
@@ -59,11 +61,22 @@ public void FlattenedDeprecationRendersMultipleLinksWithoutOuterBrackets()
}
[Test]
- public void FlattenedDeprecationRendersClickableLinkHtml()
- {
- Html.Should().Contain("href=\"https://github.com/elastic/elasticsearch/pull/268942\"");
- Html.Should().Contain("href=\"https://github.com/elastic/elasticsearch/pull/202446\"");
- Html.Should().Contain("href=\"https://github.com/elastic/elasticsearch/issues/199001\"");
- Html.Should().NotContain("[#268942, #202446]");
- }
+ public void RendersHtml() =>
+ Html.Should().MatchInlineHtmlSnapshot(
+ html: DocsHtml.Body(),
+ expected: """
+
+ 9.3.0
+
+
+ 9.3.0
+
+
+ Features and enhancements
+
+
@@ -772,7 +784,14 @@ public ChangelogLinkVisibilityInvalidTests() : base(
public void LinkVisibilityFallsBackToAuto() => Block!.LinkVisibility.Should().Be(ChangelogLinkVisibility.Auto);
[Test]
- public void EmitsWarning() => Collector.Warnings.Should().BeGreaterThan(0);
+ public void EmitsWarning() =>
+ Collector
+ .Diagnostics
+ .ToSnapshotText()
+ .Should()
+ .MatchInlineSnapshot(
+ "warning {repo}/docs/index.md:3 Invalid :link-visibility: value 'banana'. Valid values are: auto, keep-links, hide-links. Using auto."
+ );
}
///
diff --git a/tests/Elastic.Markdown.Tests/Directives/ChangelogHighlightsOptionTests.cs b/tests/Elastic.Markdown.Tests/Directives/ChangelogHighlightsOptionTests.cs
index ac0db68c88..501fc2a43e 100644
--- a/tests/Elastic.Markdown.Tests/Directives/ChangelogHighlightsOptionTests.cs
+++ b/tests/Elastic.Markdown.Tests/Directives/ChangelogHighlightsOptionTests.cs
@@ -4,7 +4,10 @@
using System.IO.Abstractions.TestingHelpers;
using AwesomeAssertions;
+using Elastic.Documentation.Testing;
using Elastic.Markdown.Myst.Directives.Changelog;
+using Nullean.Snapshots;
+using Nullean.Snapshots.Html;
namespace Elastic.Markdown.Tests.Directives;
@@ -73,20 +76,7 @@ public ChangelogHighlightsOptionDefaultOffTests() : base(
public void HighlightsDisabledByDefault() => Block!.HighlightsEnabled.Should().BeFalse();
[Test]
- public void OmitsHighlightsSection() => Html.Should().NotContain("Highlights");
-
- [Test]
- public void StillRendersHighlightedEntryUnderTypeSection()
- {
- Html.Should().Contain("Features and enhancements");
- Html.Should().Contain("Highlighted feature");
- Html.Should().Contain("Regular feature");
- Html.Should().Contain("Fixes");
- Html.Should().Contain("Bug fix");
- }
-
- [Test]
- public void ExcludesSeparatedTypesByDefault() => Html.Should().NotContain("Breaking changes");
+ public void RendersHtml() => Html.Should().MatchHtmlSnapshot(DocsHtml.Body());
[Test]
public void TocOmitsHighlights()
@@ -113,18 +103,7 @@ public ChangelogHighlightsOptionEnabledTests() : base(
public void HighlightsEnabledWhenFlagPresent() => Block!.HighlightsEnabled.Should().BeTrue();
[Test]
- public void RendersHighlightsSection() => Html.Should().Contain("Highlights");
-
- [Test]
- public void DuplicatesHighlightedEntryInTypeSection()
- {
- Html.Should().Contain("Features and enhancements");
- Html.Should().Contain("Highlighted feature");
- Html.Should().Contain("Regular feature");
- }
-
- [Test]
- public void ExcludesSeparatedTypesWithoutTypeAll() => Html.Should().NotContain("Breaking changes");
+ public void RendersHtml() => Html.Should().MatchHtmlSnapshot(DocsHtml.Body());
[Test]
public void TocIncludesHighlights()
@@ -153,12 +132,7 @@ public ChangelogHighlightsOptionWithTypeAllTests() : base(
) => FileSystem.AddFile("docs/changelog/bundles/9.3.0.yaml", new MockFileData(ChangelogHighlightsFixtures.BundleYaml));
[Test]
- public void RendersHighlightsAndSeparatedTypes()
- {
- Html.Should().Contain("Highlights");
- Html.Should().Contain("Breaking changes");
- Html.Should().Contain("Features and enhancements");
- }
+ public void RendersHtml() => Html.Should().MatchHtmlSnapshot(DocsHtml.Body());
}
///
:type: all without :highlights: — no Highlights section (breaking change from prior All behavior).
@@ -177,9 +151,7 @@ public ChangelogHighlightsOptionTypeAllWithoutFlagTests() : base(
[Test]
public void TypeAllAloneDoesNotEmitHighlightsSection()
{
- Html.Should().Contain("Breaking changes");
- Html.Should().Contain("Highlighted feature");
- Html.Should().NotContain("id=\"elasticsearch-9.3.0-highlights\"");
+ Html.Should().MatchHtmlSnapshot(DocsHtml.Body());
Block!.GeneratedTableOfContent.Should().NotContain(t => t.Heading == "Highlights");
}
}
@@ -207,21 +179,14 @@ public ChangelogHighlightsLegacyTypeHighlightTests() : base(
public void EmitsWarningPointingToHighlightsOption() =>
Collector
.Diagnostics
+ .ToSnapshotText()
.Should()
- .Contain(
- d => d.Message.Contains("Invalid :type: value 'highlight'", StringComparison.Ordinal) && d.Message.Contains(
- ":highlights:",
- StringComparison.Ordinal
- )
+ .MatchInlineSnapshot(
+ "warning {repo}/docs/index.md:3 Invalid :type: value 'highlight'. Highlights are controlled with :highlights: (not :type:). Using default behavior."
);
[Test]
- public void RendersDefaultTypeSectionsNotHighlightsOnly()
- {
- Html.Should().Contain("Features and enhancements");
- Html.Should().Contain("Highlighted feature");
- Html.Should().NotContain("id=\"elasticsearch-9.3.0-highlights\"");
- }
+ public void RendersHtml() => Html.Should().MatchHtmlSnapshot(DocsHtml.Body());
}
/// :highlights: + :description-visibility: keep-descriptions shows bodies in the Highlights section.
@@ -239,7 +204,7 @@ public ChangelogHighlightsOptionWithDescriptionsTests() : base(
) => FileSystem.AddFile("docs/changelog/bundles/9.3.0.yaml", new MockFileData(ChangelogHighlightsFixtures.BundleYaml));
[Test]
- public void ShowsDescriptionInHighlightsSection() => Html.Should().Contain("This is the highlight description.");
+ public void RendersHtml() => Html.Should().MatchHtmlSnapshot(DocsHtml.Body());
}
///
@@ -292,18 +257,7 @@ public void ParsesKeepHighlightDescriptions() =>
Block!.DescriptionVisibility.Should().Be(ChangelogDescriptionVisibility.KeepHighlightDescriptions);
[Test]
- public void ShowsDescriptionInHighlightsSection() => Html.Should().Contain("This is the highlight description.");
-
- [Test]
- public void HidesDescriptionsInTypeSections() => Html.Should().NotContain("This is the regular feature description.");
-
- [Test]
- public void StillRendersTitlesInTypeSections()
- {
- Html.Should().Contain("Features and enhancements");
- Html.Should().Contain("Highlighted feature");
- Html.Should().Contain("Regular feature");
- }
+ public void RendersHtml() => Html.Should().MatchHtmlSnapshot(DocsHtml.Body());
}
///
keep-highlight-descriptions without :highlights: hides descriptions everywhere.
@@ -349,19 +303,28 @@ public ChangelogKeepHighlightDescriptionsWithoutHighlightsTests() : base(
);
[Test]
- public void OmitsHighlightsSection() => Html.Should().NotContain("id=\"elasticsearch-9.3.0-highlights\"");
-
- [Test]
- public void HidesAllRecordDescriptions()
- {
- Html.Should().NotContain("This is the highlight description.");
- Html.Should().NotContain("This is the regular feature description.");
- }
-
- [Test]
- public void StillRendersTitles()
- {
- Html.Should().Contain("Highlighted feature");
- Html.Should().Contain("Regular feature");
- }
+ public void RendersHtml() =>
+ Html.Should().MatchInlineHtmlSnapshot(
+ html: DocsHtml.Body(),
+ expected: """
+
+ 9.3.0
+
+
+ Features and enhancements
+
+
@@ -415,9 +402,5 @@ public void MixedVersionTypesRemainSeparate()
}
[Test]
- public void RendersAllVersions()
- {
- Html.Should().Contain("9.3.0");
- Html.Should().Contain("August 5, 2025");
- }
+ public void RendersHtml() => Html.Should().MatchHtmlSnapshot(DocsHtml.Body());
}
diff --git a/tests/Elastic.Markdown.Tests/Directives/ChangelogMissingFileTests.cs b/tests/Elastic.Markdown.Tests/Directives/ChangelogMissingFileTests.cs
index a5f2619d96..7af2a3d831 100644
--- a/tests/Elastic.Markdown.Tests/Directives/ChangelogMissingFileTests.cs
+++ b/tests/Elastic.Markdown.Tests/Directives/ChangelogMissingFileTests.cs
@@ -5,7 +5,9 @@
using System.IO.Abstractions.TestingHelpers;
using AwesomeAssertions;
using Elastic.Documentation.Diagnostics;
+using Elastic.Documentation.Testing;
using Elastic.Markdown.Myst.Directives.Changelog;
+using Nullean.Snapshots;
namespace Elastic.Markdown.Tests.Directives;
@@ -65,17 +67,12 @@ public ChangelogEntryWithoutInlineContentTests() : base(
public void EmitsErrorNamingBundleAndEntry() =>
Collector
.Diagnostics
+ .ToSnapshotText()
.Should()
- .ContainSingle(
- d => d.Severity == Severity.Error && d.Message.Contains("9.3.0.yaml") && d.Message.Contains(
- "1234-referenced-entry.yaml"
- ) && d.Message.Contains("no inline content")
+ .MatchInlineSnapshot(
+ "error {repo}/docs/index.md:3 Bundle '9.3.0.yaml' entry '1234-referenced-entry.yaml' has no inline content (title and type are required); bundles must inline their entries. Skipping."
);
- [Test]
- public void ErrorIsNotAWarning() =>
- Collector.Diagnostics.Should().NotContain(d => d.Severity == Severity.Warning && d.Message.Contains("1234-referenced-entry.yaml"));
-
[Test]
public void NeverLoadsTheReferencedFile() => Block!.LoadedBundles.Should().ContainSingle(b => b.Entries.Count == 0);
}
@@ -116,7 +113,7 @@ public ChangelogInlineEntriesNoErrorTests() : base(
);
[Test]
- public void HasNoDiagnostics() => Collector.Diagnostics.Should().BeEmpty();
+ public void HasNoDiagnostics() => Collector.Diagnostics.ToSnapshotText().Should().MatchInlineSnapshot("");
[Test]
public void LoadsEntries() => Block!.LoadedBundles.Should().ContainSingle(b => b.Entries.Count == 1);
diff --git a/tests/Elastic.Markdown.Tests/Directives/ChangelogPathResolutionTests.cs b/tests/Elastic.Markdown.Tests/Directives/ChangelogPathResolutionTests.cs
index 26f79206b0..869da4ff72 100644
--- a/tests/Elastic.Markdown.Tests/Directives/ChangelogPathResolutionTests.cs
+++ b/tests/Elastic.Markdown.Tests/Directives/ChangelogPathResolutionTests.cs
@@ -4,7 +4,9 @@
using System.IO.Abstractions.TestingHelpers;
using AwesomeAssertions;
+using Elastic.Documentation.Testing;
using Elastic.Markdown.Myst.Directives.Changelog;
+using Nullean.Snapshots.Html;
namespace Elastic.Markdown.Tests.Directives;
@@ -51,7 +53,27 @@ public void PathCombinedWithDocsetRoot() =>
Block!.BundlesFolderPath.Should().EndWith("custom/path/bundles".Replace('/', Path.DirectorySeparatorChar));
[Test]
- public void RendersContent() => Html.Should().Contain("Test feature");
+ public void RendersHtml() =>
+ Html.Should().MatchInlineHtmlSnapshot(
+ html: DocsHtml.Body(),
+ expected: """
+
+ 1.0.0
+
+
+ Features and enhancements
+
+
+
+ """
+ );
}
[InheritsTests]
@@ -95,7 +117,27 @@ public void SlashPrefixIsTrimmed() =>
public void PathDoesNotContainDoubleSlashes() => Block!.BundlesFolderPath.Should().NotContain("//");
[Test]
- public void RendersContent() => Html.Should().Contain("Another feature");
+ public void RendersHtml() =>
+ Html.Should().MatchInlineHtmlSnapshot(
+ html: DocsHtml.Body(),
+ expected: """
+
+ 2.0.0
+
+
+ Features and enhancements
+
+
+
+ """
+ );
}
[InheritsTests]
@@ -159,12 +201,7 @@ public ChangelogConfigRelativePathTests() : base(
public void PublishBlockerIsNull() => Block!.PublishBlocker.Should().BeNull();
[Test]
- public void RendersAllEntries_NoFiltering()
- {
- // Directive does not apply rules.publish; all entries are shown
- Html.Should().Contain("Feature entry");
- Html.Should().Contain("Blocked entry");
- }
+ public void RendersHtml() => Html.Should().MatchHtmlSnapshot(DocsHtml.Body());
}
[InheritsTests]
@@ -226,12 +263,30 @@ public ChangelogConfigDocsetRootRelativePathTests() : base(
public void PublishBlockerIsNull() => Block!.PublishBlocker.Should().BeNull();
[Test]
- public void RendersAllEntries_NoFiltering()
- {
- // Directive does not apply rules.publish; all entries are shown
- Html.Should().Contain("Regular feature");
- Html.Should().Contain("Internal feature");
- }
+ public void RendersHtml() =>
+ Html.Should().MatchInlineHtmlSnapshot(
+ html: DocsHtml.Body(),
+ expected: """
+
+ 1.0.0
+
+
+ Features and enhancements
+
+
+ 3.0.0
+
+
+ Features and enhancements
+
+
+
+ """
+ );
}
///
@@ -318,7 +393,27 @@ public ChangelogPathEdgeCaseTests() : base(
public void ResolvesSlashPrefixedPath() => Block!.Found.Should().BeTrue();
[Test]
- public void RendersContent() => Html.Should().Contain("Edge case feature");
+ public void RendersHtml() =>
+ Html.Should().MatchInlineHtmlSnapshot(
+ html: DocsHtml.Body(),
+ expected: """
+
+ 1.0.0
+
+
+ Features and enhancements
+
+
+
+ """
+ );
}
[InheritsTests]
@@ -382,10 +477,5 @@ public void BothPathsResolveCorrectly()
}
[Test]
- public void RendersAllEntries_NoFiltering()
- {
- // Directive does not apply rules.publish; all entries are shown
- Html.Should().Contain("Combined feature");
- Html.Should().Contain("Blocked by config");
- }
+ public void RendersHtml() => Html.Should().MatchHtmlSnapshot(DocsHtml.Body());
}
diff --git a/tests/Elastic.Markdown.Tests/Directives/ChangelogReleaseDatesOptionTests.cs b/tests/Elastic.Markdown.Tests/Directives/ChangelogReleaseDatesOptionTests.cs
index 2441e7d574..57346b084d 100644
--- a/tests/Elastic.Markdown.Tests/Directives/ChangelogReleaseDatesOptionTests.cs
+++ b/tests/Elastic.Markdown.Tests/Directives/ChangelogReleaseDatesOptionTests.cs
@@ -4,7 +4,9 @@
using System.IO.Abstractions.TestingHelpers;
using AwesomeAssertions;
+using Elastic.Documentation.Testing;
using Elastic.Markdown.Myst.Directives.Changelog;
+using Nullean.Snapshots.Html;
namespace Elastic.Markdown.Tests.Directives;
@@ -44,10 +46,27 @@ public ChangelogReleaseDatesOptionDefaultOffTests() : base(
public void ReleaseDatesDisabledByDefault() => Block!.ReleaseDatesEnabled.Should().BeFalse();
[Test]
- public void OmitsReleasedLineWhenFlagOmitted() => Html.Should().NotContain("Released:");
-
- [Test]
- public void StillRendersEntries() => Html.Should().Contain("Add tracing improvements");
+ public void RendersHtml() =>
+ Html.Should().MatchInlineHtmlSnapshot(
+ html: DocsHtml.Body(),
+ expected: """
+
+ 1.34.0
+
+
+ Features and enhancements
+
+
+
+ """
+ );
}
[InheritsTests]
@@ -86,7 +105,30 @@ public ChangelogReleaseDatesOptionEnabledTests() : base(
public void ReleaseDatesEnabledWhenFlagPresent() => Block!.ReleaseDatesEnabled.Should().BeTrue();
[Test]
- public void RendersReleasedLineWhenBundleHasReleaseDate() => Html.Should().Contain("Released: April 9, 2026");
+ public void RendersHtml() =>
+ Html.Should().MatchInlineHtmlSnapshot(
+ html: DocsHtml.Body(),
+ expected: """
+
+ 1.34.0
+
+
+ Features and enhancements
+
+
+
+ """
+ );
}
[InheritsTests]
@@ -121,7 +163,27 @@ public ChangelogReleaseDatesOptionEnabledWithoutBundleDateTests() : base(
);
[Test]
- public void OmitsReleasedLineWhenBundleHasNoReleaseDate() => Html.Should().NotContain("Released:");
+ public void RendersHtml() =>
+ Html.Should().MatchInlineHtmlSnapshot(
+ html: DocsHtml.Body(),
+ expected: """
+
+ 9.3.0
+
+
+ Features and enhancements
+
+
+
+ """
+ );
}
[InheritsTests]
@@ -158,8 +220,26 @@ This release includes tracing improvements and bug fixes.
);
[Test]
- public void OmitsReleasedLineWhenFlagOmitted() => Html.Should().NotContain("Released:");
-
- [Test]
- public void RendersBundleDescription() => Html.Should().Contain("This release includes tracing improvements and bug fixes.");
+ public void RendersHtml() =>
+ Html.Should().MatchInlineHtmlSnapshot(
+ html: DocsHtml.Body(),
+ expected: """
+
+ 1.34.0
+
+
+ Features and enhancements
+
+
+
+ """
+ );
}
diff --git a/tests/Elastic.Markdown.Tests/Directives/ChangelogSubsectionsTests.cs b/tests/Elastic.Markdown.Tests/Directives/ChangelogSubsectionsTests.cs
index a3b92d57e3..a88fb7e1fd 100644
--- a/tests/Elastic.Markdown.Tests/Directives/ChangelogSubsectionsTests.cs
+++ b/tests/Elastic.Markdown.Tests/Directives/ChangelogSubsectionsTests.cs
@@ -4,7 +4,9 @@
using System.IO.Abstractions.TestingHelpers;
using AwesomeAssertions;
+using Elastic.Documentation.Testing;
using Elastic.Markdown.Myst.Directives.Changelog;
+using Nullean.Snapshots.Html;
namespace Elastic.Markdown.Tests.Directives;
@@ -53,20 +55,30 @@ public ChangelogSubsectionsDisabledByDefaultTests() : base(
public void SubsectionsPropertyDefaultsToFalse() => Block!.Subsections.Should().BeFalse();
[Test]
- public void DoesNotRenderAreaHeaders()
- {
- // When subsections is false, area headers should not be rendered
- Html.Should().NotContain("Search");
- Html.Should().NotContain("Indexing");
- }
-
- [Test]
- public void RendersEntriesWithoutGrouping()
- {
- // Both entries should be rendered without area grouping
- Html.Should().Contain("Feature in Search");
- Html.Should().Contain("Feature in Indexing");
- }
+ public void RendersHtml() =>
+ Html.Should().MatchInlineHtmlSnapshot(
+ html: DocsHtml.Body(),
+ expected: """
+
+ 9.3.0
+
+
+ Features and enhancements
+
+
+ 9.3.0
+
+
+ Features and enhancements
+
+
+
+ """
+ );
}
///
@@ -214,10 +233,28 @@ public ChangelogSubsectionsNoAreaRulesTests() : base(
);
[Test]
- public void GroupsUnderFirstArea()
- {
- // No publish rules with areas → use first area
- Html.Should().Contain("Search");
- Html.Should().Contain("Multi-area feature");
- }
+ public void RendersHtml() =>
+ Html.Should().MatchInlineHtmlSnapshot(
+ html: DocsHtml.Body(),
+ expected: """
+
+ 9.3.0
+
+
+ Features and enhancements
+
+
+
+ """
+ );
}
diff --git a/tests/Elastic.Markdown.Tests/Directives/ChangelogTocFilteringTests.cs b/tests/Elastic.Markdown.Tests/Directives/ChangelogTocFilteringTests.cs
index ec439f77bf..329d80da77 100644
--- a/tests/Elastic.Markdown.Tests/Directives/ChangelogTocFilteringTests.cs
+++ b/tests/Elastic.Markdown.Tests/Directives/ChangelogTocFilteringTests.cs
@@ -4,7 +4,10 @@
using System.IO.Abstractions.TestingHelpers;
using AwesomeAssertions;
+using Elastic.Documentation.Testing;
using Elastic.Markdown.Myst.Directives.Changelog;
+using Nullean.Snapshots;
+using Nullean.Snapshots.Html;
namespace Elastic.Markdown.Tests.Directives;
@@ -119,12 +122,7 @@ public void AnchorsIncludeOtherSection()
}
[Test]
- public void HtmlContainsAllSections()
- {
- Html.Should().Contain("Documentation");
- Html.Should().Contain("Other changes");
- Html.Should().Contain("Features and enhancements");
- }
+ public void RendersHtml() => Html.Should().MatchHtmlSnapshot(DocsHtml.Body());
}
///
@@ -211,13 +209,27 @@ public void AnchorsRetainVisibleFeaturesSection()
}
[Test]
- public void HtmlMatchesTocFiltering()
- {
- Html.Should().NotContain("Other changes");
- Html.Should().NotContain("Hidden other change");
- Html.Should().Contain("Features and enhancements");
- Html.Should().Contain("Visible feature");
- }
+ public void RendersHtml() =>
+ Html.Should().MatchInlineHtmlSnapshot(
+ html: DocsHtml.Body(),
+ expected: """
+
+ 9.3.0
+
+
+ Features and enhancements
+
+
+
+ """
+ );
}
///
@@ -278,11 +290,27 @@ public void AnchorsRetainSectionWhenSomeEntriesRemain()
}
[Test]
- public void HtmlShowsVisibleEntryOnly()
- {
- Html.Should().Contain("Visible other change");
- Html.Should().NotContain("Hidden other change");
- }
+ public void RendersHtml() =>
+ Html.Should().MatchInlineHtmlSnapshot(
+ html: DocsHtml.Body(),
+ expected: """
+
+ 9.3.0
+
+
+ Other changes
+
+
+
+ """
+ );
}
///
@@ -383,15 +411,7 @@ public void AnchorsExcludeOnlyHideFeatureFilteredSection()
}
[Test]
- public void HtmlMatchesTocAndAnchors()
- {
- Html.Should().Contain("Features and enhancements");
- Html.Should().Contain("Visible feature");
- Html.Should().Contain("Documentation");
- Html.Should().Contain("Docs entry blocked by type");
- Html.Should().NotContain(">Fixes<");
- Html.Should().NotContain("Bug fix hidden by feature");
- }
+ public void RendersHtml() => Html.Should().MatchHtmlSnapshot(DocsHtml.Body());
}
///
@@ -549,7 +569,11 @@ public void OmitsVersionFromTocWhenNoRenderableEntries()
}
[Test]
- public void OmitsVersionFromRenderedOutput() => Html.Should().NotContain("9.3.0");
+ public void OmitsVersionFromRenderedOutput()
+ {
+ Html.Should().MatchInlineHtmlSnapshot(html: DocsHtml.Body(), expected: "");
+ Collector.Diagnostics.ToSnapshotText().Should().MatchInlineSnapshot("");
+ }
[Test]
public void NoAnchorsGenerated()
diff --git a/tests/Elastic.Markdown.Tests/Directives/ChangelogTypeFilterTests.cs b/tests/Elastic.Markdown.Tests/Directives/ChangelogTypeFilterTests.cs
index 9b59b69299..2fac1f38bb 100644
--- a/tests/Elastic.Markdown.Tests/Directives/ChangelogTypeFilterTests.cs
+++ b/tests/Elastic.Markdown.Tests/Directives/ChangelogTypeFilterTests.cs
@@ -4,7 +4,10 @@
using System.IO.Abstractions.TestingHelpers;
using AwesomeAssertions;
+using Elastic.Documentation.Testing;
using Elastic.Markdown.Myst.Directives.Changelog;
+using Nullean.Snapshots;
+using Nullean.Snapshots.Html;
namespace Elastic.Markdown.Tests.Directives;
@@ -87,39 +90,7 @@ public ChangelogTypeFilterDefaultTests() : base(
public void DefaultBehaviorExcludesSeparatedTypes() => Block!.TypeFilter.Should().Be(ChangelogTypeFilter.Default);
[Test]
- public void DefaultBehaviorShowsFeatures()
- {
- Html.Should().Contain("Features and enhancements");
- Html.Should().Contain("New feature");
- }
-
- [Test]
- public void DefaultBehaviorShowsBugFixes()
- {
- Html.Should().Contain(">Fixes<");
- Html.Should().Contain("Bug fix");
- }
-
- [Test]
- public void DefaultBehaviorExcludesBreakingChanges()
- {
- Html.Should().NotContain("Breaking changes");
- Html.Should().NotContain("Breaking API change");
- }
-
- [Test]
- public void DefaultBehaviorExcludesKnownIssues()
- {
- Html.Should().NotContain("Known issues");
- Html.Should().NotContain("Known issue");
- }
-
- [Test]
- public void DefaultBehaviorExcludesDeprecations()
- {
- Html.Should().NotContain("Deprecations");
- Html.Should().NotContain("Deprecated feature");
- }
+ public void RendersHtml() => Html.Should().MatchHtmlSnapshot(DocsHtml.Body());
}
///
@@ -197,19 +168,7 @@ public ChangelogTypeFilterAllTests() : base(
public void TypeFilterIsAll() => Block!.TypeFilter.Should().Be(ChangelogTypeFilter.All);
[Test]
- public void ShowsAllEntryTypes()
- {
- Html.Should().Contain("Features and enhancements");
- Html.Should().Contain("New feature");
- Html.Should().Contain(">Fixes<");
- Html.Should().Contain("Bug fix");
- Html.Should().Contain("Breaking changes");
- Html.Should().Contain("Breaking API change");
- Html.Should().Contain("Known issues");
- Html.Should().Contain("Known issue");
- Html.Should().Contain("Deprecations");
- Html.Should().Contain("Deprecated feature");
- }
+ public void RendersHtml() => Html.Should().MatchHtmlSnapshot(DocsHtml.Body());
[Test]
public void TableOfContentsIncludesSeparatedTypeSections()
@@ -293,21 +252,30 @@ public ChangelogTypeFilterBreakingChangeTests() : base(
public void TypeFilterIsBreakingChange() => Block!.TypeFilter.Should().Be(ChangelogTypeFilter.BreakingChange);
[Test]
- public void ShowsBreakingChanges()
- {
- Html.Should().NotContain("### Breaking changes");
- Html.Should().NotContain(">Breaking changes<");
- Html.Should().Contain("Breaking API change");
- }
-
- [Test]
- public void ExcludesOtherTypes()
- {
- Html.Should().NotContain("Features and enhancements");
- Html.Should().NotContain("New feature");
- Html.Should().NotContain("Known issues");
- Html.Should().NotContain("Known issue");
- }
+ public void RendersHtml() =>
+ Html.Should().MatchInlineHtmlSnapshot(
+ html: DocsHtml.Body(),
+ expected: """
+
+ 9.3.0
+
+
+
+ """
+ );
}
///
@@ -368,20 +336,7 @@ public ChangelogTypeFilterDeprecationTests() : base(
public void TypeFilterIsDeprecation() => Block!.TypeFilter.Should().Be(ChangelogTypeFilter.Deprecation);
[Test]
- public void ShowsDeprecations()
- {
- Html.Should().NotContain("### Deprecations");
- Html.Should().NotContain(">Deprecations<");
- Html.Should().Contain("Deprecated feature");
- Html.Should().Contain("Another deprecation");
- }
-
- [Test]
- public void ExcludesOtherTypes()
- {
- Html.Should().NotContain("Features and enhancements");
- Html.Should().NotContain("New feature");
- }
+ public void RendersHtml() => Html.Should().MatchHtmlSnapshot(DocsHtml.Body());
}
///
@@ -442,20 +397,7 @@ public ChangelogTypeFilterKnownIssueTests() : base(
public void TypeFilterIsKnownIssue() => Block!.TypeFilter.Should().Be(ChangelogTypeFilter.KnownIssue);
[Test]
- public void ShowsKnownIssues()
- {
- Html.Should().NotContain("### Known issues");
- Html.Should().NotContain(">Known issues<");
- Html.Should().Contain("Known issue 1");
- Html.Should().Contain("Known issue 2");
- }
-
- [Test]
- public void ExcludesOtherTypes()
- {
- Html.Should().NotContain("Features and enhancements");
- Html.Should().NotContain("New feature");
- }
+ public void RendersHtml() => Html.Should().MatchHtmlSnapshot(DocsHtml.Body());
}
///
@@ -506,15 +448,37 @@ public ChangelogTypeFilterInvalidTests() : base(
public void FallsBackToDefaultBehavior() => Block!.TypeFilter.Should().Be(ChangelogTypeFilter.Default);
[Test]
- public void EmitsWarningForInvalidValue() => Collector.Diagnostics.Should().Contain(d => d.Message.Contains("Invalid :type: value"));
+ public void EmitsWarningForInvalidValue() =>
+ Collector
+ .Diagnostics
+ .ToSnapshotText()
+ .Should()
+ .MatchInlineSnapshot(
+ "warning {repo}/docs/index.md:3 Invalid :type: value 'invalid-value'. Valid values are: all, breaking-change, deprecation, known-issue. Using default behavior."
+ );
[Test]
- public void DefaultBehaviorIsApplied()
- {
- Html.Should().Contain("Features and enhancements");
- Html.Should().Contain("New feature");
- Html.Should().NotContain("Breaking changes");
- }
+ public void RendersHtml() =>
+ Html.Should().MatchInlineHtmlSnapshot(
+ html: DocsHtml.Body(),
+ expected: """
+
+ 9.3.0
+
+
+ Features and enhancements
+
+
+
+ """
+ );
}
///
@@ -565,11 +529,7 @@ public ChangelogTypeFilterCaseInsensitiveTests() : base(
public void AcceptsUppercaseAll() => Block!.TypeFilter.Should().Be(ChangelogTypeFilter.All);
[Test]
- public void ShowsAllTypes()
- {
- Html.Should().Contain("Features and enhancements");
- Html.Should().Contain("Breaking changes");
- }
+ public void RendersHtml() => Html.Should().MatchHtmlSnapshot(DocsHtml.Body());
}
///
@@ -636,13 +596,7 @@ public void TypeFilterAndSubsectionsBothWork()
}
[Test]
- public void ShowsAllTypesWithSubsections()
- {
- Html.Should().Contain("Features and enhancements");
- Html.Should().Contain("Search feature");
- Html.Should().Contain("Indexing feature");
- Html.Should().Contain("Breaking changes");
- }
+ public void RendersHtml() => Html.Should().MatchHtmlSnapshot(DocsHtml.Body());
}
///
@@ -791,8 +745,8 @@ public ChangelogTypeFilterEmptyKnownIssueTests() : base(
[Test]
public void OmitsEmptyVersionBlock()
{
- Html.Should().NotContain("There are no known issues associated with this release");
- Html.Should().NotContain("9.3.0");
+ Html.Should().MatchInlineHtmlSnapshot(html: DocsHtml.Body(), expected: "");
+ Collector.Diagnostics.ToSnapshotText().Should().MatchInlineSnapshot("");
}
}
@@ -833,8 +787,8 @@ public ChangelogTypeFilterEmptyBreakingChangeTests() : base(
[Test]
public void OmitsEmptyVersionBlock()
{
- Html.Should().NotContain("There are no breaking changes associated with this release");
- Html.Should().NotContain("9.3.0");
+ Html.Should().MatchInlineHtmlSnapshot(html: DocsHtml.Body(), expected: "");
+ Collector.Diagnostics.ToSnapshotText().Should().MatchInlineSnapshot("");
}
}
@@ -875,8 +829,8 @@ public ChangelogTypeFilterEmptyDeprecationTests() : base(
[Test]
public void OmitsEmptyVersionBlock()
{
- Html.Should().NotContain("There are no deprecations associated with this release");
- Html.Should().NotContain("9.3.0");
+ Html.Should().MatchInlineHtmlSnapshot(html: DocsHtml.Body(), expected: "");
+ Collector.Diagnostics.ToSnapshotText().Should().MatchInlineSnapshot("");
}
}
@@ -919,8 +873,8 @@ public ChangelogTypeFilterEmptyDefaultTests() : base(
[Test]
public void OmitsEmptyVersionBlock()
{
- Html.Should().NotContain("No new features, enhancements, or fixes");
- Html.Should().NotContain("9.3.0");
+ Html.Should().MatchInlineHtmlSnapshot(html: DocsHtml.Body(), expected: "");
+ Collector.Diagnostics.ToSnapshotText().Should().MatchInlineSnapshot("");
}
}
@@ -954,8 +908,8 @@ public ChangelogTypeFilterEmptyAllTests() : base(
[Test]
public void OmitsEmptyVersionBlock()
{
- Html.Should().NotContain("No new features, enhancements, or fixes");
- Html.Should().NotContain("9.3.0");
+ Html.Should().MatchInlineHtmlSnapshot(html: DocsHtml.Body(), expected: "");
+ Collector.Diagnostics.ToSnapshotText().Should().MatchInlineSnapshot("");
}
}
@@ -1018,12 +972,30 @@ public ChangelogTypeFilterMixedBundlesEmptyOmissionTests() : base(
}
[Test]
- public void RendersOnlyPopulatedVersions()
- {
- Html.Should().Contain("Known issue in 9.3");
- Html.Should().Contain("9.3.0");
- Html.Should().NotContain("9.2.0");
- }
+ public void RendersHtml() =>
+ Html.Should().MatchInlineHtmlSnapshot(
+ html: DocsHtml.Body(),
+ expected: """
+
+ 9.3.0
+
+
+
+ """
+ );
}
///
@@ -1056,12 +1028,18 @@ This release was pulled due to critical issues.
);
[Test]
- public void ShowsVersionAndDescriptionWithoutPlaceholder()
- {
- Html.Should().Contain("9.3.0");
- Html.Should().Contain("This release was pulled due to critical issues");
- Html.Should().NotContain("No new features, enhancements, or fixes");
- }
+ public void RendersHtml() =>
+ Html.Should().MatchInlineHtmlSnapshot(
+ html: DocsHtml.Body(),
+ expected: """
+
+ 9.3.0
+
+
@@ -1095,8 +1073,8 @@ public ChangelogEmptyBundleWithReleaseDateOnlyTests() : base(
[Test]
public void OmitsVersionBlockWhenOnlyReleaseDate()
{
- Html.Should().NotContain("9.3.0");
- Html.Should().NotContain("Released:");
+ Html.Should().MatchInlineHtmlSnapshot(html: DocsHtml.Body(), expected: "");
+ Collector.Diagnostics.ToSnapshotText().Should().MatchInlineSnapshot("");
}
}
@@ -1139,8 +1117,8 @@ public ChangelogDedicatedPageIgnoresDescriptionTests() : base(
[Test]
public void OmitsVersionBlockWhenNoMatchingEntries()
{
- Html.Should().NotContain("9.3.0");
- Html.Should().NotContain("General release notes for this version");
+ Html.Should().MatchInlineHtmlSnapshot(html: DocsHtml.Body(), expected: "");
+ Collector.Diagnostics.ToSnapshotText().Should().MatchInlineSnapshot("");
}
}
@@ -1197,14 +1175,5 @@ public ChangelogDedicatedPageWithSubsectionsTests() : base(
);
[Test]
- public void GroupsEntriesByAreaWithoutSectionHeading()
- {
- Html.Should().NotContain("### Deprecations");
- Html.Should().NotContain(">Deprecations<");
- Html.Should().NotContain("{dropdown}");
- Html.Should().Contain("Search");
- Html.Should().Contain("Search deprecation");
- Html.Should().Contain("Indexing");
- Html.Should().Contain("Indexing deprecation");
- }
+ public void RendersHtml() => Html.Should().MatchHtmlSnapshot(DocsHtml.Body());
}
diff --git a/tests/Elastic.Markdown.Tests/Directives/ChangelogVersionSortingTests.cs b/tests/Elastic.Markdown.Tests/Directives/ChangelogVersionSortingTests.cs
index 34a1512857..7a0ffbff80 100644
--- a/tests/Elastic.Markdown.Tests/Directives/ChangelogVersionSortingTests.cs
+++ b/tests/Elastic.Markdown.Tests/Directives/ChangelogVersionSortingTests.cs
@@ -4,7 +4,9 @@
using System.IO.Abstractions.TestingHelpers;
using AwesomeAssertions;
+using Elastic.Documentation.Testing;
using Elastic.Markdown.Myst.Directives.Changelog;
+using Nullean.Snapshots.Html;
namespace Elastic.Markdown.Tests.Directives;
@@ -97,20 +99,7 @@ public void RendersInDateOrderDescending()
}
[Test]
- public void RendersAllDateVersions()
- {
- Html.Should().Contain("August 15, 2025");
- Html.Should().Contain("August 5, 2025");
- Html.Should().Contain("August 1, 2025");
- }
-
- [Test]
- public void RendersEntriesForDateVersions()
- {
- Html.Should().Contain("August 15th feature");
- Html.Should().Contain("August 5th feature");
- Html.Should().Contain("August 1st feature");
- }
+ public void RendersHtml() => Html.Should().MatchHtmlSnapshot(DocsHtml.Body());
}
[InheritsTests]
@@ -230,22 +219,7 @@ public void SemverVersionsAppearBeforeDates()
}
[Test]
- public void RendersAllVersions()
- {
- Html.Should().Contain("9.3.0");
- Html.Should().Contain("9.2.0");
- Html.Should().Contain("August 5, 2025");
- Html.Should().Contain("July 1, 2025");
- }
-
- [Test]
- public void RendersAllEntries()
- {
- Html.Should().Contain("Semver 9.3.0 feature");
- Html.Should().Contain("Semver 9.2.0 feature");
- Html.Should().Contain("Date-based feature");
- Html.Should().Contain("Earlier date feature");
- }
+ public void RendersHtml() => Html.Should().MatchHtmlSnapshot(DocsHtml.Body());
}
///
@@ -336,21 +310,7 @@ public ChangelogYearMonthVersionTests() : base(
public void LoadsBundles() => Block!.LoadedBundles.Should().HaveCount(3);
[Test]
- public void RendersHeadingsAsMonthYear()
- {
- Html.Should().Contain("December 2025");
- Html.Should().Contain("October 2025");
- Html.Should().Contain("August 2025");
- }
-
- [Test]
- public void DoesNotRenderRawYearMonthInHeadings()
- {
- // The raw yyyy-MM format should only appear in slugs/anchors, not in visible headings
- Html.Should().NotContain(">2025-12<");
- Html.Should().NotContain(">2025-10<");
- Html.Should().NotContain(">2025-08<");
- }
+ public void RendersHtml() => Html.Should().MatchHtmlSnapshot(DocsHtml.Body());
[Test]
public void RendersInDescendingMonthOrder()
@@ -363,24 +323,6 @@ public void RendersInDescendingMonthOrder()
idxOct.Should().BeLessThan(idxAug, "October 2025 should appear before August 2025");
}
- [Test]
- public void PreservesOriginalSlugsForAnchors()
- {
- // Anchors should use the original yyyy-MM format, not the display format
- Html.Should().Contain("2025-12");
- Html.Should().Contain("2025-10");
- Html.Should().Contain("2025-08");
- }
-
- [Test]
- public void RendersAllEntries()
- {
- Html.Should().Contain("December feature");
- Html.Should().Contain("October feature");
- Html.Should().Contain("August feature");
- Html.Should().Contain("August bugfix");
- }
-
[Test]
public void TocUsesMonthYearHeadings()
{
@@ -463,14 +405,7 @@ public ChangelogRawVersionFallbackTests() : base(
public void LoadsBundles() => Block!.LoadedBundles.Should().HaveCount(2);
[Test]
- public void RendersNonStandardVersions()
- {
- // Both non-standard versions should be rendered (sorted lexicographically)
- Html.Should().Contain("release-alpha");
- Html.Should().Contain("release-beta");
- Html.Should().Contain("Alpha release feature");
- Html.Should().Contain("Beta release feature");
- }
+ public void RendersHtml() => Html.Should().MatchHtmlSnapshot(DocsHtml.Body());
[Test]
public void SortsLexicographically()
diff --git a/tests/Elastic.Markdown.Tests/Directives/ChangelogVersionVisibilityTests.cs b/tests/Elastic.Markdown.Tests/Directives/ChangelogVersionVisibilityTests.cs
index 3932e94f97..a3185b08c4 100644
--- a/tests/Elastic.Markdown.Tests/Directives/ChangelogVersionVisibilityTests.cs
+++ b/tests/Elastic.Markdown.Tests/Directives/ChangelogVersionVisibilityTests.cs
@@ -6,7 +6,10 @@
using Elastic.Documentation.Configuration.Assembler;
using Elastic.Documentation.Configuration.ReleaseNotes;
using Elastic.Documentation.Diagnostics;
+using Elastic.Documentation.Testing;
using Elastic.Markdown.Myst.Directives.Changelog;
+using Nullean.Snapshots;
+using Nullean.Snapshots.Html;
namespace Elastic.Markdown.Tests.Directives;
@@ -76,15 +79,37 @@ public class ChangelogVisibilityOnProductionTests() : ChangelogVersionVisibility
protected override ContentSource? GetContentSource() => ContentSource.Current;
[Test]
- public void HidesBundlesTargetingUnreleasedVersions()
- {
- Html.Should().Contain(ReleasedTitle);
- Html.Should().NotContain(UnreleasedTitle, "8.1.0 is newer than the current release (8.0.0) and production publishes 'current'");
- }
+ public void HidesBundlesTargetingUnreleasedVersions() =>
+ Html.Should().MatchInlineHtmlSnapshot(
+ html: DocsHtml.Body(),
+ expected: """
+
+ 7.9.0
+
+
+ Features and enhancements
+
+
+
+ """
+ );
[Test]
public void EmitsHintForHiddenBundle() =>
- Collector.Diagnostics.Should().Contain(d => d.Severity == Severity.Hint && d.Message.Contains("elasticsearch 8.1.0"));
+ Collector
+ .Diagnostics
+ .ToSnapshotText()
+ .Should()
+ .MatchInlineSnapshot(
+ "hint {repo}/docs/index.md:3 Hiding changelog bundle 'elasticsearch 8.1.0': it targets a version newer than the current release (8.0.0) and this build publishes the 'current' content source."
+ );
}
[InheritsTests]
@@ -93,11 +118,42 @@ public class ChangelogVisibilityOnStagingTests() : ChangelogVersionVisibilityTes
protected override ContentSource? GetContentSource() => ContentSource.Next;
[Test]
- public void ShowsUnreleasedBundlesForPreReleaseReview()
- {
- Html.Should().Contain(ReleasedTitle);
- Html.Should().Contain(UnreleasedTitle, "staging publishes 'next' so staged bundles are reviewable before release day");
- }
+ public void ShowsUnreleasedBundlesForPreReleaseReview() =>
+ Html.Should().MatchInlineHtmlSnapshot(
+ html: DocsHtml.Body(),
+ expected: """
+
+ 8.1.0
+
+
+ Features and enhancements
+
+
+
+
+ 7.9.0
+
+
+ Features and enhancements
+
+
+
+ """
+ );
}
[InheritsTests]
@@ -106,11 +162,42 @@ public class ChangelogVisibilityOnIsolatedBuildTests() : ChangelogVersionVisibil
// No override: isolated/local builds have no content source and render everything.
[Test]
- public void ShowsAllBundles()
- {
- Html.Should().Contain(ReleasedTitle);
- Html.Should().Contain(UnreleasedTitle);
- }
+ public void ShowsAllBundles() =>
+ Html.Should().MatchInlineHtmlSnapshot(
+ html: DocsHtml.Body(),
+ expected: """
+
+ 8.1.0
+
+
+ Features and enhancements
+
+
+
+
+ 7.9.0
+
+
+ Features and enhancements
+
+
+
+ """
+ );
}
///
@@ -152,5 +239,25 @@ protected override IReleaseNotesResolver GetReleaseNotesResolver() =>
);
[Test]
- public void DoesNotFilterProductsWithoutVersioningSystem() => Html.Should().Contain("Future-looking change");
+ public void RendersHtml() =>
+ Html.Should().MatchInlineHtmlSnapshot(
+ html: DocsHtml.Body(),
+ expected: """
+
+ 9.9.0
+
+
+ Features and enhancements
+
+
+
+ """
+ );
}
diff --git a/tests/Elastic.Markdown.Tests/Directives/CsvIncludeTests.cs b/tests/Elastic.Markdown.Tests/Directives/CsvIncludeTests.cs
index e8462b9cee..fa53b87102 100644
--- a/tests/Elastic.Markdown.Tests/Directives/CsvIncludeTests.cs
+++ b/tests/Elastic.Markdown.Tests/Directives/CsvIncludeTests.cs
@@ -6,7 +6,10 @@
using AwesomeAssertions;
using Elastic.Documentation.Configuration;
using Elastic.Documentation.FileSystems;
+using Elastic.Documentation.Testing;
using Elastic.Markdown.Myst.Directives.CsvInclude;
+using Nullean.Snapshots;
+using Nullean.Snapshots.Html;
namespace Elastic.Markdown.Tests.Directives;
@@ -161,7 +164,30 @@ protected override void AddToFileSystem(MockFileSystem fileSystem) =>
Search,[Text](https://www.google.com)"));
[Test]
- public void RendersMarkdownLinkAsLink() => Html.Should().Contain(">Text
| Name | +Link | +
|---|---|
| Search | ++ Text + | +
"); + public void RendersHtml() => + Html.Should().MatchInlineHtmlSnapshot( + html: DocsHtml.Body(), + options: MermaidSnapshots.Options, + expected: """ ++ ++ """ + ); } // Allowlisted semantic classes render correctly with site palette colors baked into SVG. @@ -204,13 +284,23 @@ flowchart LR """) { [Test] - public void RendersMermaidContainer() => Html.Should().Contain(""); + public void RendersHtml() => + Html.Should().MatchInlineHtmlSnapshot( + html: DocsHtml.Body(), + options: MermaidSnapshots.Options, + expected: """ ++ """ ); } } @@ -248,7 +256,7 @@ public class StorybookBodyTests() : StorybookRegistryTest( ) { [Test] - public void RendersBodyContent() => Html.Should().Contain("Supporting details for this story."); + public void RendersHtml() => Html.Should().MatchHtmlSnapshot(DocsHtml.Body()); } [InheritsTests] @@ -267,9 +275,19 @@ public void WarnsAndFallsBackToDefaultHeight() Block!.Height.Should().Be(400); Collector .Diagnostics + .ToSnapshotText() .Should() - .ContainSingle(d => d.Severity == Severity.Warning && d.Message.Contains(":height: must be a positive integer")); - Html.Should().Contain("height:400px"); + .MatchInlineSnapshot( + "warning {repo}/docs/index.md:3 storybook directive :height: must be a positive integer. Got 'tall', using default 400px." + ); + Html.Should().MatchInlineHtmlSnapshot( + html: DocsHtml.Body(), + expected: """ + + """ + ); } } @@ -283,7 +301,12 @@ public class StorybookMissingRegistryTests() : DirectiveTest+ ++ """ + ); [Test] - public void RendersImgElement() => Html.Should().Contain("Collector.Diagnostics.Should().BeEmpty(); + public void EmitsNoDiagnostics() => Collector.Diagnostics.ToSnapshotText().Should().MatchInlineSnapshot(""); [Test] public void SvgContainsWarningFillColor() => ReadMermaidSvgs()[0].Should().Contain("#fdf3d8"); @@ -227,10 +317,23 @@ public class MermaidPieDataPaletteTests() : DirectiveTest(""" """) { [Test] - public void RendersImgElement() => Html.Should().Contain("
Collector.Diagnostics.Should().BeEmpty(); + public void RendersHtml() => + Html.Should().MatchInlineHtmlSnapshot( + html: DocsHtml.Body(), + options: MermaidSnapshots.Options, + expected: """ +
+ ++ """ + ); + + [Test] + public void EmitsNoDiagnostics() => Collector.Diagnostics.ToSnapshotText().Should().MatchInlineSnapshot(""); [Test] public void UsesThemePalette() => ReadMermaidSvgs()[0].Should().Contain("#3788ff"); // blue-elastic-70 diff --git a/tests/Elastic.Markdown.Tests/Directives/PageCardBlockTests.cs b/tests/Elastic.Markdown.Tests/Directives/PageCardBlockTests.cs index d9eaf63e1e..9cca34c73c 100644 --- a/tests/Elastic.Markdown.Tests/Directives/PageCardBlockTests.cs +++ b/tests/Elastic.Markdown.Tests/Directives/PageCardBlockTests.cs @@ -6,8 +6,10 @@ using AwesomeAssertions; using Elastic.Documentation.Diagnostics; using Elastic.Documentation.Navigation; +using Elastic.Documentation.Testing; using Elastic.Markdown.IO; using Elastic.Markdown.Myst.Directives.PageCard; +using Nullean.Snapshots; namespace Elastic.Markdown.Tests.Directives; @@ -30,7 +32,7 @@ protected override void AddToFileSystem(MockFileSystem fileSystem) => public void ResolvesUrlViaNavigationLookup() => Block!.ResolvedUrl.Should().Be("/other-page"); [Test] - public void EmitsNoErrors() => Collector.Diagnostics.Should().NotContain(d => d.Severity == Severity.Error); + public void EmitsNoErrors() => Collector.Diagnostics.ToSnapshotText().Should().MatchInlineSnapshot(""); } ///@@ -56,7 +58,7 @@ protected override void ConfigureDocumentationSet(DocumentationSet set) => public void ResolvesUrlWithRehomedPrefix() => Block!.ResolvedUrl.Should().Be("/reference/rehomed/other-page"); [Test] - public void EmitsNoErrors() => Collector.Diagnostics.Should().NotContain(d => d.Severity == Severity.Error); + public void EmitsNoErrors() => Collector.Diagnostics.ToSnapshotText().Should().MatchInlineSnapshot(""); } /// @@ -81,7 +83,7 @@ protected override void ConfigureDocumentationSet(DocumentationSet set) => public void ResolvesUrlWithRehomedPrefixAndAnchor() => Block!.ResolvedUrl.Should().Be("/reference/rehomed/other-page#install"); [Test] - public void EmitsNoErrors() => Collector.Diagnostics.Should().NotContain(d => d.Severity == Severity.Error); + public void EmitsNoErrors() => Collector.Diagnostics.ToSnapshotText().Should().MatchInlineSnapshot(""); } /// Namespace-style link (no .md extension) probes for /index.md variant. @@ -98,7 +100,7 @@ protected override void AddToFileSystem(MockFileSystem fileSystem) => public void ResolvesIndexPageUrl() => Block!.ResolvedUrl.Should().Be("/subdir"); [Test] - public void EmitsNoErrors() => Collector.Diagnostics.Should().NotContain(d => d.Severity == Severity.Error); + public void EmitsNoErrors() => Collector.Diagnostics.ToSnapshotText().Should().MatchInlineSnapshot(""); } ///Absolute HTTP URLs are rejected with an error. @@ -112,5 +114,11 @@ public class PageCardAbsoluteUrlErrorTests() : DirectiveTest( { [Test] public void EmitsErrorForAbsoluteUrl() => - Collector.Diagnostics.Should().Contain(d => d.Severity == Severity.Error && d.Message.Contains("absolute URL")); + Collector + .Diagnostics + .ToSnapshotText() + .Should() + .MatchInlineSnapshot( + "error {repo}/docs/index.md:3 page-card url must be a local .md path or crosslink, not an absolute URL: https://example.com/page" + ); } diff --git a/tests/Elastic.Markdown.Tests/Directives/RelatedLearningTests.cs b/tests/Elastic.Markdown.Tests/Directives/RelatedLearningTests.cs index 08d997ac22..ef9405c8dd 100644 --- a/tests/Elastic.Markdown.Tests/Directives/RelatedLearningTests.cs +++ b/tests/Elastic.Markdown.Tests/Directives/RelatedLearningTests.cs @@ -4,7 +4,9 @@ using AwesomeAssertions; using Elastic.Documentation.Diagnostics; +using Elastic.Documentation.Testing; using Elastic.Markdown.Myst.Directives.RelatedLearning; +using Nullean.Snapshots; namespace Elastic.Markdown.Tests.Directives; @@ -58,7 +60,7 @@ public void PageTocIncludesDefaultSlug() } [Test] - public void EmitsNoDiagnostics() => Collector.Diagnostics.Should().BeEmpty(); + public void EmitsNoDiagnostics() => Collector.Diagnostics.ToSnapshotText().Should().MatchInlineSnapshot(""); private static int CountOccurrences(string haystack, string needle) { @@ -137,8 +139,9 @@ public void EmitsErrorAndRendersNothing() { Collector .Diagnostics + .ToSnapshotText() .Should() - .Contain(d => d.Severity == Severity.Error && d.Message.Contains("unknown catalog ID 'not-a-module'")); + .MatchInlineSnapshot("error {repo}/docs/index.md:3 {related-learning} unknown catalog ID 'not-a-module'."); Block!.Items.Should().BeEmpty(); Html.Should().NotContain("related-learning"); File.PageTableOfContent.Should().NotContainKey(RelatedLearningBlock.DefaultSlug); @@ -159,8 +162,9 @@ public void WarnsAndKeepsFirstOccurrence() Block!.Items.Should().ContainSingle().Which.Id.Should().Be("apm-with-elastic"); Collector .Diagnostics + .ToSnapshotText() .Should() - .Contain(d => d.Severity == Severity.Warning && d.Message.Contains("duplicate catalog ID 'apm-with-elastic'")); + .MatchInlineSnapshot("warning {repo}/docs/index.md:3 {related-learning} duplicate catalog ID 'apm-with-elastic' was skipped."); } } @@ -175,8 +179,9 @@ public void EmitsErrorWhenArgumentMissing() { Collector .Diagnostics + .ToSnapshotText() .Should() - .Contain(d => d.Severity == Severity.Error && d.Message.Contains("requires at least one catalog ID as an argument")); + .MatchInlineSnapshot("error {repo}/docs/index.md:3 {related-learning} requires at least one catalog ID as an argument."); Block!.Items.Should().BeEmpty(); } } diff --git a/tests/Elastic.Markdown.Tests/Directives/StepperTocOptionTests.cs b/tests/Elastic.Markdown.Tests/Directives/StepperTocOptionTests.cs index 00ff3d9fa5..1d41add0f9 100644 --- a/tests/Elastic.Markdown.Tests/Directives/StepperTocOptionTests.cs +++ b/tests/Elastic.Markdown.Tests/Directives/StepperTocOptionTests.cs @@ -4,7 +4,9 @@ using AwesomeAssertions; using Elastic.Documentation.Diagnostics; +using Elastic.Documentation.Testing; using Elastic.Markdown.Myst.Directives.Stepper; +using Nullean.Snapshots.Html; namespace Elastic.Markdown.Tests.Directives; @@ -31,13 +33,22 @@ public void Toc_WhenDefault_IncludesStepTitle() } [Test] - public void Render_WhenDefault_UsesHeadingElement() - { - Html.Should().Contain(" + Html.Should().MatchInlineHtmlSnapshot( + html: DocsHtml.Body(), + expected: """ +
++ """ + ); } [InheritsTests] @@ -62,15 +73,22 @@ public void Toc_WhenTocFalse_OmitsStepTitle() } [Test] - public void Render_WhenTocFalse_UsesDiv() - { - Html.Should().NotContain("+
+- +
++ Install +
+First install the dependencies.
++ Html.Should().MatchInlineHtmlSnapshot( + html: DocsHtml.Body(), + expected: """ +
++ """ + ); } [InheritsTests] @@ -99,12 +117,7 @@ public void Toc_WhenTocFalse_KeepsInternalHeading() } [Test] - public void Render_WhenTocFalse_KeepsInternalHeadingLevel() - { - Html.Should().Contain("+
+- +
++ Install ++First install the dependencies.
+Html.Should().MatchHtmlSnapshot(DocsHtml.Body()); } [InheritsTests] @@ -140,10 +153,25 @@ public void Hint_WhenNoPrecedingHeading_NamesOutlineLevel() } [Test] - public void Render_WhenNoPrecedingHeading_AdjustsInternalHeading() - { - Html.Should().Contain("
+ Html.Should().MatchInlineHtmlSnapshot( + html: DocsHtml.Body(), + expected: """ + + """ + ); } diff --git a/tests/Elastic.Markdown.Tests/Directives/StorybookTests.cs b/tests/Elastic.Markdown.Tests/Directives/StorybookTests.cs index 13731bb2d2..7c9b987c01 100644 --- a/tests/Elastic.Markdown.Tests/Directives/StorybookTests.cs +++ b/tests/Elastic.Markdown.Tests/Directives/StorybookTests.cs @@ -6,7 +6,10 @@ using AwesomeAssertions; using Elastic.Documentation; using Elastic.Documentation.Diagnostics; +using Elastic.Documentation.Testing; using Elastic.Markdown.Myst.Directives.Storybook; +using Nullean.Snapshots; +using Nullean.Snapshots.Html; namespace Elastic.Markdown.Tests.Directives; @@ -104,15 +107,7 @@ public void ResolvesStory() } [Test] - public void RendersInlineStory() - { - Html.Should().Contain("
Html.Should().MatchHtmlSnapshot(DocsHtml.Body()); } /// Deterministic @@ -169,8 +164,14 @@ public class StorybookDisallowedRegistryVariableTests() : StorybookRegistryTest( public void WarnsAndLeavesExpressionLiteral() => Collector .Diagnostics + .ToSnapshotText(firstLineOnly: true) .Should() - .Contain(d => d.Severity == Severity.Warning && d.Message.Contains("not allow-listed for interpolation")); + .MatchInlineSnapshot( + """ + warning {repo}/docs/docset.yml 'storybook.registry' references environment variable 'AWS_SECRET_ACCESS_KEY' which is not allow-listed for interpolation and is left literal. Allowed: KIBANA_STORYBOOK_REGISTRY. + error {repo}/docs/index.md:3 storybook registry could not be read: ${AWS_SECRET_ACCESS_KEY:-docs_registry.json} + """ + ); } [InheritsTests] @@ -204,8 +205,11 @@ public class StorybookStructuredReferenceWrongStorybookTests() : StorybookRegist public void DoesNotFallbackToAnotherStorybook() => Collector .Diagnostics + .ToSnapshotText() .Should() - .Contain(d => d.Message.Contains("does not contain id 'kibana:content_management:ai-components-aibutton--default'")); + .MatchInlineSnapshot( + "error {repo}/docs/index.md:3 storybook registry does not contain id 'kibana:content_management:ai-components-aibutton--default'." + ); } [InheritsTests] @@ -230,9 +234,13 @@ public class StorybookIframeTests() : StorybookRegistryTest(""" public void RendersIframeFallback() { Block!.HasInlineStory.Should().BeFalse(); - Html.Should().Contain("so storybook interpolation tests don't depend on the host shell. ( ) { [Test] - public void EmitsError() => Collector.Diagnostics.Should().Contain(d => d.Message.Contains("requires docset.yml storybook.registry")); + public void EmitsError() => + Collector + .Diagnostics + .ToSnapshotText() + .Should() + .MatchInlineSnapshot("error {repo}/docs/index.md:3 storybook directive requires docset.yml storybook.registry."); } [InheritsTests] @@ -293,7 +316,12 @@ public class StorybookMissingIdTests() : StorybookRegistryTest(""" """) { [Test] - public void EmitsError() => Collector.Diagnostics.Should().Contain(d => d.Message.Contains("requires :id: or :project:")); + public void EmitsError() => + Collector + .Diagnostics + .ToSnapshotText() + .Should() + .MatchInlineSnapshot("error {repo}/docs/index.md:3 storybook directive requires :id: or :project:."); } [InheritsTests] @@ -309,6 +337,7 @@ public class StorybookPositionalArgumentWarningTests() : StorybookRegistryTest( public void EmitsWarning() => Collector .Diagnostics + .ToSnapshotText() .Should() - .ContainSingle(d => d.Severity == Severity.Warning && d.Message.Contains("ignores positional arguments")); + .MatchInlineSnapshot("warning {repo}/docs/index.md:3 storybook directive ignores positional arguments. Use properties instead."); } diff --git a/tests/Elastic.Markdown.Tests/Directives/TableDirectiveTests.cs b/tests/Elastic.Markdown.Tests/Directives/TableDirectiveTests.cs index 9db847b13d..9f075867c9 100644 --- a/tests/Elastic.Markdown.Tests/Directives/TableDirectiveTests.cs +++ b/tests/Elastic.Markdown.Tests/Directives/TableDirectiveTests.cs @@ -4,7 +4,10 @@ using AwesomeAssertions; using Elastic.Documentation.Diagnostics; +using Elastic.Documentation.Testing; using Elastic.Markdown.Myst.Directives.Table; +using Nullean.Snapshots; +using Nullean.Snapshots.Html; namespace Elastic.Markdown.Tests.Directives; @@ -26,13 +29,28 @@ public class TableDirectiveBasicTests() : DirectiveTest ( public void SetsCorrectDirectiveType() => Block!.Directive.Should().Be("table"); [Test] - public void RendersTableInOutput() - { - Html.Should().Contain("table-wrapper"); - Html.Should().Contain(" + Html.Should().MatchInlineHtmlSnapshot( + html: DocsHtml.Body(), + expected: """ +
++ """ + ); } [InheritsTests] @@ -57,13 +75,7 @@ public void ParsesWidthsOption() } [Test] - public void RendersColgroupWithWidths() - { - Html.Should().Contain("colgroup"); - Html.Should().Contain("table-layout:fixed"); - Html.Should().Contain("width:33.33%"); - Html.Should().Contain("width:66.67%"); - } + public void RendersHtml() => Html.Should().MatchHtmlSnapshot(DocsHtml.Body()); } [InheritsTests] @@ -88,7 +100,7 @@ public void MapsDescriptionTo4_8() } [Test] - public void RendersColgroup() => Html.Should().Contain("colgroup"); + public void RendersHtml() => Html.Should().MatchHtmlSnapshot(DocsHtml.Body()); } [InheritsTests] @@ -108,7 +120,30 @@ public class TableDirectiveAutoPresetTests() : DirectiveTest+ +
++ + + +head a +head b ++ + +a +b +Block!.ColumnWidths.Should().BeEmpty(); [Test] - public void DoesNotInjectColgroup() => Html.Should().NotContain("colgroup"); + public void RendersHtml() => + Html.Should().MatchInlineHtmlSnapshot( + html: DocsHtml.Body(), + expected: """ + ++ """ + ); } [InheritsTests] @@ -128,7 +163,28 @@ public class TableDirectiveMatrixTests() : DirectiveTest+ +
++ + + +a +b +c ++ + +1 +2 +3 +( public void ParsesMatrixOption() => Block!.Matrix.Should().BeTrue(); [Test] - public void RendersMatrixClass() => Html.Should().Contain("table-wrapper table-matrix"); + public void RendersHtml() => + Html.Should().MatchInlineHtmlSnapshot( + html: DocsHtml.Body(), + expected: """ + ++ """ + ); } [InheritsTests] @@ -143,7 +199,28 @@ public class TableDirectiveWithoutMatrixTests() : DirectiveTest+ +
++ + + +head a +head b ++ + +a +b +Html.Should().NotContain("table-matrix"); + public void RendersHtml() => + Html.Should().MatchInlineHtmlSnapshot( + html: DocsHtml.Body(), + expected: """ + ++ """ + ); } [InheritsTests] @@ -163,14 +240,30 @@ public class TableDirectiveFilterableTests() : DirectiveTest+ +
++ + + +head a +head b ++ + +a +b +Block!.Filterable.Should().BeTrue(); [Test] - public void WrapsTableInHostElement() - { - Html.Should().Contain(" "); - Html.Should().Contain(" "); - } - - [Test] - public void KeepsServerRenderedTableInsideHost() => Html.Should().Contain(" + Html.Should().MatchInlineHtmlSnapshot( + html: DocsHtml.Body(), + expected: """ ++ + """ + ); } [InheritsTests] @@ -188,7 +281,28 @@ public class TableDirectiveWithoutFilterableTests() : DirectiveTest+++ +
++ + + +head a +head b ++ + +a +b +Block!.Filterable.Should().BeFalse(); [Test] - public void DoesNotWrapTable() => Html.Should().NotContain("filterable-table"); + public void RendersHtml() => + Html.Should().MatchInlineHtmlSnapshot( + html: DocsHtml.Body(), + expected: """ + ++ """ + ); } [InheritsTests] @@ -207,12 +321,7 @@ public class TableDirectiveFilterableWithMatrixAndWidthsTests() : DirectiveTest< ) { [Test] - public void ComposesWithMatrixAndWidths() - { - Html.Should().Contain("+ +
++ + + +head a +head b ++ + +a +b + Html.Should().MatchHtmlSnapshot(DocsHtml.Body()); } [InheritsTests] @@ -230,7 +339,11 @@ public class TableDirectiveWidthCountMismatchTests() : DirectiveTest- Collector.Diagnostics.Should().Contain(d => d.Severity == Severity.Error && d.Message.Contains("does not match")); + Collector + .Diagnostics + .ToSnapshotText() + .Should() + .MatchInlineSnapshot("error {repo}/docs/index.md:3 Column width count (3) does not match table column count (2)."); } [InheritsTests] @@ -248,7 +361,11 @@ public class TableDirectiveWidthsSumErrorTests() : DirectiveTest - Collector.Diagnostics.Should().Contain(d => d.Severity == Severity.Error && d.Message.Contains("sum to 12")); + Collector + .Diagnostics + .ToSnapshotText() + .Should() + .MatchInlineSnapshot("error {repo}/docs/index.md:3 Column widths must sum to 12 (Bootstrap grid). Got sum of 8."); } [InheritsTests] @@ -262,7 +379,13 @@ public class TableDirectiveNoTableTests() : DirectiveTest (" { [Test] public void EmitsError() => - Collector.Diagnostics.Should().Contain(d => d.Severity == Severity.Error && d.Message.Contains("pipe table")); + Collector + .Diagnostics + .ToSnapshotText() + .Should() + .MatchInlineSnapshot( + "error {repo}/docs/index.md:3 Table directive must contain a pipe table. Add a table using Markdown pipe syntax." + ); } [InheritsTests] @@ -280,7 +403,13 @@ public class TableDirectiveInvalidWidthsTests() : DirectiveTest - Collector.Diagnostics.Should().Contain(d => d.Severity == Severity.Error && d.Message.Contains("Invalid widths value")); + Collector + .Diagnostics + .ToSnapshotText() + .Should() + .MatchInlineSnapshot( + "error {repo}/docs/index.md:3 Invalid widths value 'foo'. Use preset (auto, description) or dash-separated integers 1-12 that sum to 12 (e.g., 4-8, 4-4-4)." + ); } [InheritsTests] @@ -298,7 +427,13 @@ public class TableDirectiveOutOfRangeWidthsTests() : DirectiveTest - Collector.Diagnostics.Should().Contain(d => d.Severity == Severity.Error && d.Message.Contains("Invalid widths value")); + Collector + .Diagnostics + .ToSnapshotText() + .Should() + .MatchInlineSnapshot( + "error {repo}/docs/index.md:3 Invalid widths value '0-12'. Use preset (auto, description) or dash-separated integers 1-12 that sum to 12 (e.g., 4-8, 4-4-4)." + ); } [InheritsTests] @@ -320,5 +455,9 @@ public class TableDirectiveMultipleTablesTests() : DirectiveTest - Collector.Diagnostics.Should().Contain(d => d.Severity == Severity.Error && d.Message.Contains("exactly one pipe table")); + Collector + .Diagnostics + .ToSnapshotText() + .Should() + .MatchInlineSnapshot("error {repo}/docs/index.md:3 Table directive must contain exactly one pipe table."); } diff --git a/tests/Elastic.Markdown.Tests/Directives/UnsupportedTests.cs b/tests/Elastic.Markdown.Tests/Directives/UnsupportedTests.cs index 4f1189197a..b5f6861937 100644 --- a/tests/Elastic.Markdown.Tests/Directives/UnsupportedTests.cs +++ b/tests/Elastic.Markdown.Tests/Directives/UnsupportedTests.cs @@ -4,7 +4,9 @@ using AwesomeAssertions; using Elastic.Documentation.Diagnostics; +using Elastic.Documentation.Testing; using Elastic.Markdown.Myst.Directives; +using Nullean.Snapshots; namespace Elastic.Markdown.Tests.Directives; @@ -27,15 +29,7 @@ A regular paragraph. public void SetsCorrectDirectiveType() => Block!.Directive.Should().Be(directive); [Test] - public void TracksASingleWarning() => Collector.Warnings.Should().Be(1); - - [Test] - public void EmitsUnsupportedWarnings() - { - Collector.Diagnostics.Should().NotBeNullOrEmpty().And.HaveCount(1); - Collector.Diagnostics.Should().OnlyContain(d => d.Severity == Severity.Warning); - Collector.Diagnostics.Should().OnlyContain(d => d.Message.StartsWith($"Directive block '{directive}' is unsupported.")); - } + public void EmitsUnsupportedWarnings() => Collector.Diagnostics.ToSnapshotText().Should().MatchSnapshot(); } [InheritsTests] diff --git a/tests/Elastic.Markdown.Tests/Directives/VectorSizingBlockTests.cs b/tests/Elastic.Markdown.Tests/Directives/VectorSizingBlockTests.cs index ad8bd22acc..f66599ebb7 100644 --- a/tests/Elastic.Markdown.Tests/Directives/VectorSizingBlockTests.cs +++ b/tests/Elastic.Markdown.Tests/Directives/VectorSizingBlockTests.cs @@ -3,7 +3,9 @@ // See the LICENSE file in the project root for more information using AwesomeAssertions; +using Elastic.Documentation.Testing; using Elastic.Markdown.Myst.Directives.VectorSizing; +using Nullean.Snapshots.Html; namespace Elastic.Markdown.Tests.Directives; @@ -20,5 +22,6 @@ public class VectorSizingBlockTests() : DirectiveTest (""" public void SetsCorrectDirectiveType() => Block!.Directive.Should().Be("vector-sizing-calculator"); [Test] - public void RendersCustomElement() => Html.Should().Contain(" "); + public void RendersHtml() => + Html.Should().MatchInlineHtmlSnapshot(html: DocsHtml.Body(), expected: " "); } diff --git a/tests/Elastic.Markdown.Tests/Directives/VersionTests.cs b/tests/Elastic.Markdown.Tests/Directives/VersionTests.cs index 57a7990842..fc5c9db91e 100644 --- a/tests/Elastic.Markdown.Tests/Directives/VersionTests.cs +++ b/tests/Elastic.Markdown.Tests/Directives/VersionTests.cs @@ -4,8 +4,10 @@ using AwesomeAssertions; using Elastic.Documentation; +using Elastic.Documentation.Testing; using Elastic.Documentation.Versions; using Elastic.Markdown.Myst.Directives.Version; +using Nullean.Snapshots; namespace Elastic.Markdown.Tests.Directives; @@ -74,7 +76,7 @@ public class SimpleVersion() : VersionValidationTests("7.17") public void SetsVersion() => Block!.Version.Should().Be(new SemVersion(7, 17, 0)); [Test] - public void HasNoError() => Collector.Diagnostics.Should().BeEmpty(); + public void HasNoError() => Collector.Diagnostics.ToSnapshotText().Should().MatchInlineSnapshot(""); } [InheritsTests] @@ -82,7 +84,7 @@ public class MajorVersionOnly() : VersionValidationTests("8") { [Test] public void HasError() => - Collector.Diagnostics.Should().HaveCount(1).And.Contain(d => d.Message.Contains("'8' is not a valid version")); + Collector.Diagnostics.ToSnapshotText().Should().MatchInlineSnapshot("error {repo}/docs/index.md:3 '8' is not a valid version"); } [InheritsTests] @@ -90,5 +92,5 @@ public class BranchVersion() : VersionValidationTests("8.x") { [Test] public void HasError() => - Collector.Diagnostics.Should().HaveCount(1).And.Contain(d => d.Message.Contains("'8.x' is not a valid version")); + Collector.Diagnostics.ToSnapshotText().Should().MatchInlineSnapshot("error {repo}/docs/index.md:3 '8.x' is not a valid version"); }