mirror of
https://github.com/facebook/docusaurus.git
synced 2025-06-07 05:12:31 +02:00
test: ensure consistent CSS ordering (#6222)
This commit is contained in:
parent
c45d9c6a89
commit
7adc1c0cdb
9 changed files with 178 additions and 3 deletions
11
website/_dogfooding/clientModuleCSS.css
Normal file
11
website/_dogfooding/clientModuleCSS.css
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Used to test CSS insertion order */
|
||||||
|
.test-marker-site-client-module {
|
||||||
|
content: "site-client-module";
|
||||||
|
}
|
|
@ -55,6 +55,18 @@ const dogfoodingPluginInstances = [
|
||||||
routeBasePath: '/tests/pages',
|
routeBasePath: '/tests/pages',
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
|
||||||
|
/** @type {import('@docusaurus/types').Plugin} */
|
||||||
|
function clientModuleTestPlugin() {
|
||||||
|
return {
|
||||||
|
getClientModules() {
|
||||||
|
return [
|
||||||
|
require.resolve('./clientModuleExample.ts'),
|
||||||
|
require.resolve('./clientModuleCSS.css'),
|
||||||
|
];
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
exports.dogfoodingPluginInstances = dogfoodingPluginInstances;
|
exports.dogfoodingPluginInstances = dogfoodingPluginInstances;
|
||||||
|
|
|
@ -118,7 +118,6 @@ const config = {
|
||||||
'static',
|
'static',
|
||||||
path.join(__dirname, '_dogfooding/_asset-tests'),
|
path.join(__dirname, '_dogfooding/_asset-tests'),
|
||||||
],
|
],
|
||||||
clientModules: [require.resolve('./_dogfooding/clientModuleExample.ts')],
|
|
||||||
themes: ['live-codeblock'],
|
themes: ['live-codeblock'],
|
||||||
plugins: [
|
plugins: [
|
||||||
FeatureRequestsPlugin,
|
FeatureRequestsPlugin,
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
"deploy": "docusaurus deploy",
|
"deploy": "docusaurus deploy",
|
||||||
"clear": "docusaurus clear",
|
"clear": "docusaurus clear",
|
||||||
"serve": "docusaurus serve",
|
"serve": "docusaurus serve",
|
||||||
|
"test:css-order": "node testCSSOrder.js",
|
||||||
"write-translations": "docusaurus write-translations",
|
"write-translations": "docusaurus write-translations",
|
||||||
"write-heading-ids": "docusaurus write-heading-ids",
|
"write-heading-ids": "docusaurus write-heading-ids",
|
||||||
"start:baseUrl": "cross-env BASE_URL='/build/' yarn start",
|
"start:baseUrl": "cross-env BASE_URL='/build/' yarn start",
|
||||||
|
@ -17,8 +18,8 @@
|
||||||
"start:blogOnly": "cross-env yarn start --config=docusaurus.config-blog-only.js",
|
"start:blogOnly": "cross-env yarn start --config=docusaurus.config-blog-only.js",
|
||||||
"build:blogOnly": "cross-env yarn build --config=docusaurus.config-blog-only.js",
|
"build:blogOnly": "cross-env yarn build --config=docusaurus.config-blog-only.js",
|
||||||
"build:fast": "cross-env BUILD_FAST=true yarn build --locale en",
|
"build:fast": "cross-env BUILD_FAST=true yarn build --locale en",
|
||||||
"netlify:build:production": "yarn docusaurus write-translations && yarn netlify:crowdin:delay && yarn netlify:crowdin:uploadSources && yarn netlify:crowdin:downloadTranslations && yarn build",
|
"netlify:build:production": "yarn docusaurus write-translations && yarn netlify:crowdin:delay && yarn netlify:crowdin:uploadSources && yarn netlify:crowdin:downloadTranslations && yarn build && yarn test:css-order",
|
||||||
"netlify:build:deployPreview": "yarn docusaurus write-translations --locale fr --messagePrefix '(fr) ' && yarn build",
|
"netlify:build:deployPreview": "yarn docusaurus write-translations --locale fr --messagePrefix '(fr) ' && yarn build && yarn test:css-order",
|
||||||
"netlify:crowdin:delay": "node delayCrowdin.js",
|
"netlify:crowdin:delay": "node delayCrowdin.js",
|
||||||
"netlify:crowdin:wait": "node waitForCrowdin.js",
|
"netlify:crowdin:wait": "node waitForCrowdin.js",
|
||||||
"netlify:crowdin:downloadTranslations": "yarn netlify:crowdin:wait && yarn --cwd .. crowdin:download:website",
|
"netlify:crowdin:downloadTranslations": "yarn netlify:crowdin:wait && yarn --cwd .. crowdin:download:website",
|
||||||
|
|
|
@ -171,3 +171,11 @@ div[class^='announcementBar_'] {
|
||||||
width: 1px;
|
width: 1px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Used to test CSS insertion order */
|
||||||
|
.test-marker-site-custom-css-unique-rule {
|
||||||
|
content: "site-custom-css-unique-rule";
|
||||||
|
}
|
||||||
|
.test-marker-site-custom-css-shared-rule {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
|
@ -153,3 +153,8 @@
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Used to test CSS insertion order */
|
||||||
|
.test-marker-site-index-page {
|
||||||
|
content: "site-index-page";
|
||||||
|
}
|
||||||
|
|
17
website/src/theme/Layout/index.tsx
Normal file
17
website/src/theme/Layout/index.tsx
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import type {Props} from '@theme/Layout';
|
||||||
|
import Layout from '@theme-original/Layout';
|
||||||
|
|
||||||
|
// This component is only used to test for CSS insertion order
|
||||||
|
import './styles.module.css';
|
||||||
|
|
||||||
|
export default function LayoutWrapper(props: Props): JSX.Element {
|
||||||
|
return <Layout {...props} />;
|
||||||
|
}
|
12
website/src/theme/Layout/styles.module.css
Normal file
12
website/src/theme/Layout/styles.module.css
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Used to test CSS insertion order */
|
||||||
|
.test-marker-theme-layout {
|
||||||
|
content: "theme-layout";
|
||||||
|
}
|
||||||
|
|
110
website/testCSSOrder.js
Normal file
110
website/testCSSOrder.js
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
/*
|
||||||
|
This verifies CSS ordering on the Docusaurus site itself,
|
||||||
|
|
||||||
|
There are multiple ways to provide some CSS to Docusaurus
|
||||||
|
and Docusaurus should guarantee a consistent CSS ordering over time
|
||||||
|
|
||||||
|
See also
|
||||||
|
- https://github.com/facebook/docusaurus/issues/3678
|
||||||
|
- https://github.com/facebook/docusaurus/pull/5987
|
||||||
|
|
||||||
|
TODO we should probably add a real e2e test in core instead of using our own website?
|
||||||
|
Current solution looks good-enough for now
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
// TODO temporary, the current order is bad and we should change/fix that
|
||||||
|
const EXPECTED_CSS_MARKERS = [
|
||||||
|
// Note, Infima and site classes are optimized/deduplicated and put at the top
|
||||||
|
// We don't agree yet on what should be the order for those classes
|
||||||
|
// See https://github.com/facebook/docusaurus/pull/6222
|
||||||
|
'.markdown>h2',
|
||||||
|
'.button--outline.button--active',
|
||||||
|
'.DocSearch-Hit-content-wrapper',
|
||||||
|
'.navbar__title',
|
||||||
|
'--ifm-color-scheme:light',
|
||||||
|
'.test-marker-site-custom-css-shared-rule',
|
||||||
|
'.col[class*=col--]',
|
||||||
|
'.padding-vert--xl',
|
||||||
|
'.footer__link-item',
|
||||||
|
'.pagination__item',
|
||||||
|
'.pills__item',
|
||||||
|
'.tabs__item',
|
||||||
|
|
||||||
|
// Test markers
|
||||||
|
'.test-marker-site-custom-css-unique-rule',
|
||||||
|
'.test-marker-site-client-module',
|
||||||
|
'.test-marker-theme-layout',
|
||||||
|
'.test-marker-site-index-page',
|
||||||
|
|
||||||
|
// lazy loaded lib
|
||||||
|
'.DocSearch-Modal',
|
||||||
|
];
|
||||||
|
|
||||||
|
const cssDirName = path.join(__dirname, 'build', 'assets', 'css');
|
||||||
|
|
||||||
|
const cssFileNames = fs
|
||||||
|
.readdirSync(cssDirName)
|
||||||
|
.filter((file) => file.endsWith('.css'));
|
||||||
|
|
||||||
|
if (cssFileNames.length !== 1) {
|
||||||
|
throw new Error('unexpected: more than 1 css file');
|
||||||
|
}
|
||||||
|
const cssFile = path.join(cssDirName, cssFileNames[0]);
|
||||||
|
|
||||||
|
console.log('Inspecting CSS file for test CSS markers', cssFile);
|
||||||
|
|
||||||
|
const cssFileContent = fs.readFileSync(cssFile, 'utf8');
|
||||||
|
|
||||||
|
const cssMarkersWithPositions = EXPECTED_CSS_MARKERS.map((marker) => {
|
||||||
|
const position = cssFileContent.indexOf(marker);
|
||||||
|
return {marker, position};
|
||||||
|
});
|
||||||
|
|
||||||
|
const missingCSSMarkers = cssMarkersWithPositions
|
||||||
|
.filter((m) => m.position === -1)
|
||||||
|
.map((m) => m.marker);
|
||||||
|
|
||||||
|
if (missingCSSMarkers.length > 0) {
|
||||||
|
throw new Error(
|
||||||
|
`Some expected CSS marker classes could not be found in file ${cssFile}: \n- ${missingCSSMarkers.join(
|
||||||
|
'\n- ',
|
||||||
|
)}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore#_sortby-and-_orderby
|
||||||
|
const sortBy = (key) => (a, b) =>
|
||||||
|
// eslint-disable-next-line no-nested-ternary
|
||||||
|
a[key] > b[key] ? 1 : b[key] > a[key] ? -1 : 0;
|
||||||
|
|
||||||
|
const sortedCSSMarkers = cssMarkersWithPositions
|
||||||
|
.concat()
|
||||||
|
.sort(sortBy('position'))
|
||||||
|
.map(({marker}) => marker);
|
||||||
|
|
||||||
|
if (JSON.stringify(sortedCSSMarkers) === JSON.stringify(EXPECTED_CSS_MARKERS)) {
|
||||||
|
console.log(`Test CSS markers were found in the expected order:
|
||||||
|
- ${sortedCSSMarkers.join('\n- ')}`);
|
||||||
|
} else {
|
||||||
|
throw new Error(`Test CSS markers were found in an incorrect order.
|
||||||
|
|
||||||
|
Expected order:
|
||||||
|
- ${EXPECTED_CSS_MARKERS.join('\n- ')};
|
||||||
|
|
||||||
|
Actual order:
|
||||||
|
- ${sortedCSSMarkers.join('\n- ')};
|
||||||
|
|
||||||
|
CSS file: ${cssFile}
|
||||||
|
`);
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue