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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 22 additions & 26 deletions scripts/create-testenv.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ function runCommand(command, args, options = {}) {

if (result.status !== 0) {
throw new Error(
`Command failed: ${command} ${args.join(' ')} (status ${result.status ?? 1}${result.signal ? `, signal ${result.signal}` : ''})`,
`Command failed: ${command} ${args.join(' ')} (status ${result.status ?? 1}${result.signal ? `, signal ${result.signal}` : ''})`
);
}
}
Expand Down Expand Up @@ -191,10 +191,7 @@ function upsertHeadStyle(html, markerAttribute, styleTag) {

function applySeoDirectivesToHtml(
html,
{
canonicalUrl = ROOT_CANONICAL_URL,
robotsDirectives = TESTENV_ROBOTS_DIRECTIVES,
} = {},
{ canonicalUrl = ROOT_CANONICAL_URL, robotsDirectives = TESTENV_ROBOTS_DIRECTIVES } = {}
) {
let nextHtml = html;

Expand Down Expand Up @@ -495,13 +492,22 @@ const TESTENV_HIDE_HEADER_STYLE = `
}
</style>`;

function hideTopHeaderInBuiltHtml(html) {
if (html.includes('data-testenv-hide-header')) {
return html;
}

return html.replace('</head>', `${TESTENV_HIDE_HEADER_STYLE}\n </head>`);
}

async function hideTopHeaderInBuiltPage(pagePath) {
const html = await readFile(pagePath, 'utf8');
if (html.includes('data-testenv-hide-header')) {
const nextHtml = hideTopHeaderInBuiltHtml(html);

if (nextHtml === html) {
return;
}

const nextHtml = html.replace('</head>', `${TESTENV_HIDE_HEADER_STYLE}\n </head>`);
await writeFile(pagePath, nextHtml, 'utf8');
}
Comment thread
Copilot marked this conversation as resolved.
Comment thread
greptile-apps[bot] marked this conversation as resolved.

Expand Down Expand Up @@ -541,11 +547,7 @@ async function createTemporaryDocsAppPlaceholder() {
}

async function removeTemporaryDocsAppPlaceholder() {
await writeFile(
docsAppPlaceholderPath,
'<p>This will be overwritten during the npm build.</p>',
'utf8',
);
await writeFile(docsAppPlaceholderPath, '<p>This will be overwritten during the npm build.</p>', 'utf8');
}

async function main() {
Expand Down Expand Up @@ -578,26 +580,19 @@ async function main() {
await createTemporaryDocsAppPlaceholder();

try {
runCommand(
'pnpm',
['--dir', 'docs-src', 'exec', 'docusaurus', 'build', '--out-dir', '../testenv/site'],
{
env: {
DOCS_BASE_URL: fullSiteBaseUrl,
DOCS_SITE_URL: 'https://eviltester.github.io',
DOCS_TEST_BUILD: 'true',
DOCS_TEST_CANONICAL_SITE_URL: TESTENV_CANONICAL_SITE_URL,
},
runCommand('pnpm', ['--dir', 'docs-src', 'exec', 'docusaurus', 'build', '--out-dir', '../testenv/site'], {
env: {
DOCS_BASE_URL: fullSiteBaseUrl,
DOCS_SITE_URL: 'https://eviltester.github.io',
DOCS_TEST_BUILD: 'true',
DOCS_TEST_CANONICAL_SITE_URL: TESTENV_CANONICAL_SITE_URL,
},
);
});
} finally {
await removeTemporaryDocsAppPlaceholder();
}

await copyWebBuildIntoDirectory(tempWebDir, fullSiteDir);
await hideTopHeaderInBuiltPage(path.join(fullSiteDir, 'app.html'));
await hideTopHeaderInBuiltPage(path.join(fullSiteDir, 'generator.html'));
await hideTopHeaderInBuiltPage(path.join(fullSiteDir, 'combinatorial.html'));
await rm(tempWebDir, {
recursive: true,
force: true,
Expand Down Expand Up @@ -627,6 +622,7 @@ export {
createLlmsTxt,
createSiteRobotsTxt,
createTestenvRobotsTxt,
hideTopHeaderInBuiltHtml,
renderIndexPage,
};

Expand Down
44 changes: 43 additions & 1 deletion tests/integration/create-testenv-seo.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
createLlmsTxt,
createSiteRobotsTxt,
createTestenvRobotsTxt,
hideTopHeaderInBuiltHtml,
renderIndexPage,
} from '../../scripts/create-testenv.mjs';

Expand Down Expand Up @@ -47,7 +48,9 @@ describe('create-testenv SEO helpers', () => {
});

test('injects the test environment indicator into rewritten html pages', () => {
const html = applySeoDirectivesToHtml('<!doctype html><html><head><title>Storybook</title></head><body></body></html>');
const html = applySeoDirectivesToHtml(
'<!doctype html><html><head><title>Storybook</title></head><body></body></html>'
);

expect(html).toContain('data-testenv-indicator');
expect(html).toContain('content: "Test Environment"');
Expand All @@ -57,4 +60,43 @@ describe('create-testenv SEO helpers', () => {
expect(html).toContain('box-shadow: none;');
expect(html).toContain('font: 700 6px/1.2 Arial, Helvetica, sans-serif;');
});

test('SEO rewrite keeps existing headers intact while adding the test environment indicator', () => {
const sourceHtml = `
<!doctype html>
<html>
<head><title>App</title></head>
<body>
<div class="header" data-role="theme-toggle-host">AnyWayData</div>
</body>
</html>
`;

const html = applySeoDirectivesToHtml(sourceHtml, {
canonicalUrl: `${TESTENV_CANONICAL_SITE_URL}/app.html`,
});

expect(html).toContain('data-testenv-indicator');
expect(html).toContain('class="header"');
expect(html).not.toContain('data-testenv-hide-header');
expect(html).toContain('<link rel="canonical" href="https://anywaydata.com/app.html" />');
});

test('standalone app pages can be rewritten to hide the top header', () => {
const sourceHtml = `
<!doctype html>
<html>
<head><title>Standalone App</title></head>
<body>
<div class="header" data-role="theme-toggle-host">AnyWayData</div>
</body>
</html>
`;

const html = hideTopHeaderInBuiltHtml(sourceHtml);

expect(html).toContain('data-testenv-hide-header');
expect(html).toContain('.header {');
expect(html).toContain('display: none !important;');
});
});