159 lines
5.0 KiB
TypeScript
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);
|
|
});
|
|
});
|