diff --git a/bin/storybook/check-links.mjs b/bin/storybook/check-links.mjs index 52752f4..fb341cb 100644 --- a/bin/storybook/check-links.mjs +++ b/bin/storybook/check-links.mjs @@ -3,7 +3,7 @@ import { existsSync, mkdtempSync, readFileSync, readdirSync, rmSync } from 'node import { tmpdir } from 'node:os'; import { extname, join, relative, sep } from 'node:path'; import { fileURLToPath } from 'node:url'; -import { legacyReactIds, sharedDocIds } from './routes.mjs'; +import { legacyReactIds, sharedDocIds, migratedReactId } from './routes.mjs'; import { validateLinks } from './link-validation.mjs'; const root = fileURLToPath(new URL('../../', import.meta.url)); @@ -49,7 +49,7 @@ if (built) { const errors = []; for (const id of legacyReactIds) { - const canonical = sharedDocIds.includes(id) ? id : `react-${id}`; + const canonical = sharedDocIds.includes(id) ? id : migratedReactId(id); if (!indexes.react.entries[canonical]) errors.push(`Missing migrated entry: ${canonical}`); } for (const id of sharedDocIds) { @@ -74,7 +74,7 @@ for (const [group, names] of [ for (const name of names) { const primaryStory = name === 'input' ? 'primary-default-with-label-and-helper-text' : 'default'; for (const variant of ['docs', primaryStory]) { - const id = `${group}-${name}--${variant}`; + const id = `components-${group}-${name}--${variant}`; if (!indexes.webComponents.entries[id]) errors.push(`Missing native Web Components entry: ${id}`); } } diff --git a/bin/storybook/link-validation.test.mjs b/bin/storybook/link-validation.test.mjs index fb8bc5d..abec66f 100644 --- a/bin/storybook/link-validation.test.mjs +++ b/bin/storybook/link-validation.test.mjs @@ -5,35 +5,43 @@ import { validateLinks } from './link-validation.mjs'; const indexes = { react: { entries: { - 'react-atoms-button--docs': { type: 'docs' }, + 'react-components-atoms-button--docs': { type: 'docs' }, 'theme-tokens-colors--docs': { type: 'docs' }, }, }, - webComponents: { entries: { 'introduction-overview--overview': { type: 'story' } } }, + webComponents: { + entries: { + 'introduction-overview--overview': { type: 'story' }, + 'components-atoms-button--default': { type: 'story' }, + }, + }, }; test('validates canonical, composed and child deep links', () => { const result = validateLinks( ` - [Button](?path=/docs/react-atoms-button--docs) + [Button](?path=/docs/react-components-atoms-button--docs) [Colors](?path=/docs/theme-tokens-colors--docs) https://storybook.cto-rnd-system-design.griddynamics.net/web-components/?path=/story/introduction-overview--overview ?path=/story/web-components_introduction-overview--overview - iframe.html?id=react-atoms-button--docs&viewMode=docs + ?path=/story/web-components_components-atoms-button--default + iframe.html?id=react-components-atoms-button--docs&viewMode=docs `, indexes ); - assert.equal(result.checked, 5); + assert.equal(result.checked, 6); assert.deepEqual(result.errors, []); }); test('catches stale, nonexistent, incorrectly typed and bare routes', () => { for (const href of [ '?path=/docs/atoms-button--docs', + '?path=/docs/react-atoms-button--docs', + '?path=/story/web-components_atoms-button--default', '?path=/docs/react-nonexistent--docs', '?path=/docs/react-theme-tokens-colors--docs', - '?path=/story/react-atoms-button--docs', - '/docs/react-atoms-button--docs', + '?path=/story/react-components-atoms-button--docs', + '/docs/react-components-atoms-button--docs', ]) assert.ok(validateLinks(href, indexes).errors.length > 0, href); }); diff --git a/bin/storybook/native-checks.mjs b/bin/storybook/native-checks.mjs index d37fbf7..58db51d 100644 --- a/bin/storybook/native-checks.mjs +++ b/bin/storybook/native-checks.mjs @@ -6,7 +6,8 @@ export async function checkNativeStories(page, base) { const stories = Object.values(index.entries).filter( (entry) => entry.type === 'story' && - (/^(Atoms|Molecules)\//.test(entry.title) || entry.title.startsWith('Layout & Structure/')) && + (/^Components\/(Atoms|Molecules)\//.test(entry.title) || + entry.title.startsWith('Components/Layout & Structure/')) && !entry.id.endsWith('--default-tokens') ); const names = new Set(); @@ -17,7 +18,7 @@ export async function checkNativeStories(page, base) { sliderdots: 'slider-dots', }; for (const story of stories) { - const name = story.title.split('/')[1].toLowerCase(); + const name = story.title.split('/')[2].toLowerCase(); names.add(name); await page.goto(`${base}/web-components/iframe.html?id=${story.id}&viewMode=story`); const tag = `gd-${tags[name] ?? name}`; @@ -105,7 +106,7 @@ export async function checkNativeStories(page, base) { }), detail ); - await open('layout-structure-chatcontainer--interactive-demo'); + await open('components-layout-structure-chatcontainer--interactive-demo'); const chatContainer = page.locator('gd-chat-container'); await page.waitForFunction(() => document.querySelector('gd-chat-container')?.isOpen === true); await chatContainer.evaluate((element) => element.close()); @@ -120,7 +121,7 @@ export async function checkNativeStories(page, base) { }) ); assert.deepEqual(await toggleEvent, { open: false }); - await open('layout-structure-column--default'); + await open('components-layout-structure-column--default'); assert.equal( await page .locator('gd-column') @@ -128,16 +129,16 @@ export async function checkNativeStories(page, base) { .evaluate((element) => getComputedStyle(element.shadowRoot.querySelector('[part="root"]')).flexDirection), 'column' ); - await open('layout-structure-row--default'); + await open('components-layout-structure-row--default'); assert.equal(await page.locator('gd-row').evaluate((element) => element.getAttribute('display')), 'inline-flex'); - await open('layout-structure-flexcontainer--default'); + await open('components-layout-structure-flexcontainer--default'); assert.equal( await page .locator('gd-flex-container') .evaluate((element) => getComputedStyle(element.shadowRoot.querySelector('[part="root"]')).display), 'flex' ); - await open('layout-structure-portal--rendering-in-target'); + await open('components-layout-structure-portal--rendering-in-target'); await page.getByText('Show Portal', { exact: true }).click(); assert.equal( await page @@ -147,7 +148,7 @@ export async function checkNativeStories(page, base) { 1 ); assert.equal(await page.locator('gd-portal').evaluate((element) => element.portalRoot), null); - await open('layout-structure-portal--with-wrapper-as-tag-main'); + await open('components-layout-structure-portal--with-wrapper-as-tag-main'); await page.getByText('Show Portal', { exact: true }).click(); assert.equal(await page.locator('gd-portal').evaluate((element) => element.portalRoot?.tagName), 'MAIN'); assert.deepEqual( @@ -159,7 +160,7 @@ export async function checkNativeStories(page, base) { ); await page.getByText('Hide', { exact: true }).click(); assert.equal(await page.locator('gd-portal').count(), 0); - await open('layout-structure-scroll--interactive-example'); + await open('components-layout-structure-scroll--interactive-example'); const scroll = page.locator('gd-scroll'); await page.waitForFunction(() => { const element = document.querySelector('gd-scroll'); @@ -226,7 +227,7 @@ export async function checkNativeStories(page, base) { await page.mouse.move(trackBox.x + trackBox.width / 2, trackBox.y + trackBox.height - 2); await page.mouse.up(); await page.waitForFunction(() => document.querySelector('gd-scroll').scrollTop > 100); - await open('layout-structure-scroll--vertical-scroll-only'); + await open('components-layout-structure-scroll--vertical-scroll-only'); await page.waitForFunction(() => document.querySelector('gd-scroll')?.scrollHeight > 198); assert.deepEqual( await page.locator('gd-scroll').evaluate((element) => ({ @@ -236,7 +237,7 @@ export async function checkNativeStories(page, base) { })), { extent: [298, 500], vertical: true, horizontal: false } ); - await open('layout-structure-scroll--horizontal-scroll-only'); + await open('components-layout-structure-scroll--horizontal-scroll-only'); await page.waitForFunction(() => document.querySelector('gd-scroll')?.scrollWidth > 298); assert.deepEqual( await page.locator('gd-scroll').evaluate((element) => ({ @@ -246,7 +247,7 @@ export async function checkNativeStories(page, base) { })), { extent: [1020, 198], vertical: false, horizontal: true } ); - await open('layout-structure-scroll--auto-hide-scrollbars'); + await open('components-layout-structure-scroll--auto-hide-scrollbars'); await page.waitForFunction(() => document.querySelector('gd-scroll')?.shadowRoot?.querySelector('[part~="vertical-scrollbar"]') ); @@ -268,7 +269,7 @@ export async function checkNativeStories(page, base) { ); await page.waitForTimeout(1250); assert.equal(await autoHideScrollbar.evaluate((element) => getComputedStyle(element).opacity), '0'); - await open('layout-structure-scroll--auto-hide-vertical-only'); + await open('components-layout-structure-scroll--auto-hide-vertical-only'); await page.waitForFunction(() => document.querySelector('gd-scroll')?.scrollHeight === 980); assert.deepEqual( await page.locator('gd-scroll').evaluate((element) => ({ @@ -278,10 +279,10 @@ export async function checkNativeStories(page, base) { })), { extent: [298, 980], vertical: true, horizontal: false } ); - await open('atoms-button--disabled-button'); + await open('components-atoms-button--disabled-button'); await page.getByRole('button', { name: 'Disabled Button', exact: true }).waitFor(); assert.ok(await page.getByRole('button', { name: 'Disabled Button', exact: true }).isDisabled()); - await open('atoms-input--primary-default-with-label-and-helper-text'); + await open('components-atoms-input--primary-default-with-label-and-helper-text'); // The story's play function types "hello" after render; wait for it so it cannot overwrite the fill below. await page.waitForFunction( () => document.querySelector('gd-input')?.shadowRoot?.querySelector('input')?.value === 'hello' @@ -289,14 +290,14 @@ export async function checkNativeStories(page, base) { // The wrapping