Files
nrwl--nx/astro-docs/e2e/cli-subcommand-formatting.spec.ts
2026-07-13 12:38:36 +08:00

159 lines
5.0 KiB
TypeScript

import { test, expect } from '@playwright/test';
test.describe('CLI sub-command formatting', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/docs/reference/nx-commands');
await expect(
page.getByRole('heading', { name: 'Nx Commands' })
).toBeVisible();
});
test('parent commands render as h2 and sub-commands as h3', async ({
page,
}) => {
const mainContent = page.getByTestId('main-pane');
// "nx show" should be an h2 (top-level parent command)
const showHeading = mainContent.getByRole('heading', {
name: 'nx show',
level: 2,
exact: true,
});
await expect(showHeading).toBeVisible();
// "nx show projects" should be an h3 (sub-command nested under parent)
const showProjectsHeading = mainContent.getByRole('heading', {
name: 'nx show projects',
level: 3,
exact: true,
});
await expect(showProjectsHeading).toBeVisible();
// "nx show project" should also be an h3
const showProjectHeading = mainContent.getByRole('heading', {
name: 'nx show project',
level: 3,
exact: true,
});
await expect(showProjectHeading).toBeVisible();
});
test('sub-command usage blocks show the full command name', async ({
page,
}) => {
const mainContent = page.getByTestId('main-pane');
// Find the "nx show projects" section and verify its usage block
// The usage code block should contain "nx show projects", not "nx projects"
const showProjectsHeading = mainContent.getByRole('heading', {
name: 'nx show projects',
level: 3,
exact: true,
});
await expect(showProjectsHeading).toBeVisible();
// Get the section between "nx show projects" heading and the next heading.
// We look for a code block containing the correct usage pattern.
const codeBlocks = mainContent.locator('pre code');
const allCodeTexts = await codeBlocks.allTextContents();
// There should be a usage block with "nx show projects" (full sub-command name)
expect(allCodeTexts.some((text) => text.includes('nx show projects'))).toBe(
true
);
// There should NOT be a usage block with just "nx projects" (missing parent)
expect(
allCodeTexts.some(
(text) => text.match(/^nx projects/) || text.match(/\nnx projects/)
)
).toBe(false);
});
test('nested sub-commands beyond two levels are documented', async ({
page,
}) => {
const mainContent = page.getByTestId('main-pane');
// "nx show target inputs" is a third-level command — it should render as h3
// alongside other sub-commands and include its usage block.
const showTargetInputsHeading = mainContent.getByRole('heading', {
name: 'nx show target inputs',
level: 3,
exact: true,
});
await expect(showTargetInputsHeading).toBeVisible();
const showTargetOutputsHeading = mainContent.getByRole('heading', {
name: 'nx show target outputs',
level: 3,
exact: true,
});
await expect(showTargetOutputsHeading).toBeVisible();
const codeBlocks = mainContent.locator('pre code');
const allCodeTexts = await codeBlocks.allTextContents();
expect(
allCodeTexts.some((text) => text.includes('nx show target inputs'))
).toBe(true);
});
test('release sub-commands use correct heading and usage format', async ({
page,
}) => {
const mainContent = page.getByTestId('main-pane');
// "nx release" should be h2
const releaseHeading = mainContent.getByRole('heading', {
name: 'nx release',
level: 2,
exact: true,
});
await expect(releaseHeading).toBeVisible();
// "nx release version" should be h3
const releaseVersionHeading = mainContent.getByRole('heading', {
name: 'nx release version',
level: 3,
exact: true,
});
await expect(releaseVersionHeading).toBeVisible();
// Verify usage block includes the full command
const codeBlocks = mainContent.locator('pre code');
const allCodeTexts = await codeBlocks.allTextContents();
expect(
allCodeTexts.some((text) => text.includes('nx release version'))
).toBe(true);
});
test('options and examples are h4 headings excluded from the TOC', async ({
page,
}) => {
const mainContent = page.getByTestId('main-pane');
// Options/Examples should be h4 headings — linkable but below the TOC threshold (h2-h3)
const sharedOptionsHeading = mainContent.getByRole('heading', {
name: 'Shared Options',
level: 4,
});
await expect(sharedOptionsHeading.first()).toBeVisible();
const optionsHeading = mainContent.getByRole('heading', {
name: 'Options',
level: 4,
});
await expect(optionsHeading.first()).toBeVisible();
// They should NOT appear as h2 or h3 (which would put them in the TOC)
await expect(
mainContent.getByRole('heading', { name: 'Options', level: 2 })
).toHaveCount(0);
await expect(
mainContent.getByRole('heading', { name: 'Options', level: 3 })
).toHaveCount(0);
});
});