Skip to content

Commit 03f6b14

Browse files
committed
chore: Detect and report missing css styles
1 parent 3bf5819 commit 03f6b14

File tree

12 files changed

+137
-7
lines changed

12 files changed

+137
-7
lines changed

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ src/index.ts
99
src/test-utils/dom/index.ts
1010
src/test-utils/selectors
1111
src/icon/generated
12-
src/internal/generated/custom-css-properties/index.*
12+
src/internal/generated/custom-css-properties
1313
vendor/generated-*.txt
1414
# IDEs
1515
.vscode
1616
# System
17-
.DS_Store
17+
.DS_Store

build-tools/tasks/clean.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ module.exports = task('clean', () => {
1414
`${workspace.targetPath}/**`,
1515
`${workspace.staticSitePath}/**`,
1616
`${workspace.generatedTestUtils}/**`,
17+
`${workspace.generatedPath}/custom-css-properties/**`,
1718
`node_modules/.cache`,
1819
],
1920
{ glob: true }

build-tools/tasks/generate-custom-css-properties.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
3-
const customCssPropertiesList = require('../../src/internal/generated/custom-css-properties/list');
43
const path = require('path');
5-
const { writeFile } = require('../utils/files');
64
const { getHashDigest } = require('loader-utils');
5+
const customCssPropertiesList = require('../utils/custom-css-properties');
6+
const { writeFile } = require('../utils/files');
7+
const workspace = require('../utils/workspace');
78

8-
const outputBasePath = path.join(__dirname, '../../src/internal/generated/custom-css-properties');
9+
const outputBasePath = path.join(workspace.generatedPath, 'custom-css-properties');
910
const hash = getHashDigest(Buffer.from(JSON.stringify(customCssPropertiesList)), 'md5', 'base36', 6);
1011

1112
const getHashedProperty = property => {
@@ -32,6 +33,9 @@ function writeSassFile() {
3233
writeFile(
3334
filepath,
3435
`
36+
// Build environment
37+
$awsui-commit-hash: ${workspace.gitCommitVersion};
38+
// Manually managed CSS-variables
3539
${customCssPropertiesList.map(property => `$${property}: ${getHashedProperty(property)};`).join('\n')}
3640
`
3741
);

build-tools/tasks/generate-environment.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ function writeEnvironmentFile(theme) {
1010
const values = {
1111
PACKAGE_SOURCE: workspace.packageSource,
1212
PACKAGE_VERSION: workspace.packageVersion,
13+
GIT_SHA: workspace.gitCommitVersion,
1314
THEME: theme.name,
1415
ALWAYS_VISUAL_REFRESH: !!theme.alwaysVisualRefresh,
1516
};
File renamed without changes.

build-tools/utils/workspace.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ module.exports = {
1111
isProd: process.env.NODE_ENV === 'production',
1212
packageSource,
1313
packageVersion,
14+
gitCommitVersion,
1415
sourcePath: 'src',
1516
generatedPath: 'src/internal/generated',
1617
generatedTestUtils: 'src/test-utils/selectors',

src/internal/base-component/styles.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,8 @@
99
*/
1010
@use 'awsui:globals';
1111
@use '../styles/global.scss';
12+
@use '../generated/custom-css-properties' as custom-styles;
13+
14+
:root {
15+
--awsui-version-info-#{custom-styles.$awsui-commit-hash}: true;
16+
}

src/internal/environment.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@
55
export const THEME: string;
66
export const PACKAGE_SOURCE: string;
77
export const PACKAGE_VERSION: string;
8+
export const GIT_SHA: string;
89
/** Indicates that the current theme is always in visual refresh mode. */
910
export const ALWAYS_VISUAL_REFRESH: boolean;
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
import { GIT_SHA } from '../../../../../lib/components/internal/environment';
5+
import { checkMissingStyles } from '../../../../../lib/components/internal/hooks/use-base-component/styles-check';
6+
import { metrics } from '../../../../../lib/components/internal/metrics';
7+
8+
jest.mock('../../../../../lib/components/internal/environment', () => ({
9+
...jest.requireActual('../../../../../lib/components/internal/environment'),
10+
PACKAGE_VERSION: '3.0.0 (abc)',
11+
GIT_SHA: 'abc',
12+
}));
13+
14+
let consoleWarnSpy: jest.SpyInstance;
15+
let sendPanoramaMetricSpy: jest.SpyInstance;
16+
17+
const style = document.createElement('style');
18+
document.body.append(style);
19+
20+
beforeEach(() => {
21+
style.textContent = ``;
22+
consoleWarnSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
23+
sendPanoramaMetricSpy = jest.spyOn(metrics, 'sendOpsMetricObject').mockImplementation(() => {});
24+
});
25+
26+
afterEach(() => {
27+
jest.resetAllMocks();
28+
});
29+
30+
test('should pass the check if styles found', () => {
31+
// using :root does not work in JSDOM: https://github.com/jsdom/jsdom/issues/3563
32+
style.textContent = `
33+
body {
34+
--awsui-version-info-${GIT_SHA}: true;
35+
}
36+
`;
37+
checkMissingStyles();
38+
expect(consoleWarnSpy).not.toHaveBeenCalled();
39+
expect(sendPanoramaMetricSpy).not.toHaveBeenCalled();
40+
});
41+
42+
test('should detect missing styles', () => {
43+
checkMissingStyles();
44+
expect(consoleWarnSpy).toHaveBeenCalledWith(
45+
'Missing Cloudscape CSS for theme "default", version "3.0.0 (abc)", and git sha "abc".'
46+
);
47+
expect(sendPanoramaMetricSpy).toHaveBeenCalledWith('awsui-missing-css-asset', {});
48+
});
49+
50+
test('should report missing styles if a different version found', () => {
51+
style.textContent = `
52+
body {
53+
--awsui-version-info-c4d5e6: true;
54+
}
55+
`;
56+
checkMissingStyles();
57+
expect(consoleWarnSpy).toHaveBeenCalledWith(
58+
'Missing Cloudscape CSS for theme "default", version "3.0.0 (abc)", and git sha "abc".'
59+
);
60+
expect(sendPanoramaMetricSpy).toHaveBeenCalledWith('awsui-missing-css-asset', {});
61+
});

src/internal/hooks/use-base-component/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { AnalyticsMetadata } from '../../analytics/interfaces';
1313
import { PACKAGE_SOURCE, PACKAGE_VERSION, THEME } from '../../environment';
1414
import { getVisualTheme } from '../../utils/get-visual-theme';
1515
import { useVisualRefresh } from '../use-visual-mode';
16+
import { useMissingStylesCheck } from './styles-check';
1617

1718
export interface InternalBaseComponentProps<T = any> {
1819
__internalRootRef?: MutableRefObject<T | null> | null;
@@ -32,6 +33,7 @@ export default function useBaseComponent<T = any>(
3233
const theme = getVisualTheme(THEME, isVisualRefresh);
3334
useComponentMetrics(componentName, { packageSource: PACKAGE_SOURCE, packageVersion: PACKAGE_VERSION, theme }, config);
3435
useFocusVisible();
36+
useMissingStylesCheck();
3537
const elementRef = useComponentMetadata<T>(
3638
componentName,
3739
{ packageName: PACKAGE_SOURCE, version: PACKAGE_VERSION, theme },

0 commit comments

Comments
 (0)