Skip to content

Commit 4cfff23

Browse files
committed
End-to-end testing, CI script, and JavaScript QoL improvements:
- **Environment variable formatting** - Updated environment variable configuration from array format to object format to comply with Lefthook schema validation requirements. - **Unified link testing** - Consolidated multiple product-specific link testing commands into a single `e2e-links` command that processes all staged Markdown and HTML files across content directories. - **Package script integration** - Modified commands to use centralized yarn scripts instead of direct execution, improving maintainability and consistency. - **Source information extraction** - Enhanced to correctly extract and report source information from frontmatter. - **URL and source mapping** - Improved handling of URL to source path mapping for better reporting. - **Ignored anchor links configuration** - Added proper exclusion of behavior-triggering anchor links (like tab navigation) to prevent false positives. - **Request options correction** - Fixed Cypress request options to ensure `failOnStatusCode` is properly set when `retryOnStatusCodeFailure` is enabled. - **Improved error reporting** - Enhanced error reporting with more context about broken links. - **New test scripts added** - Added centralized testing scripts for link checking and codeblock validation. - **Product-specific test commands** - Added commands for each product version (InfluxDB v2, v3 Core, Enterprise, Cloud, etc.). - **API docs testing** - Added specialized commands for testing API documentation links. - **Comprehensive test runners** - Added commands to run all tests of a specific type (`test:links:all`, `test:codeblocks:all`). - Fix Docker build command and update CONTRIBUTING. chore(js): JavaScript QoL improvements: - Refactor main.js with a componentRegistry object and clear initialization of components and globals - Add a standard index.js with all necessary exports. - Update javascript.html to use the index.js - Remove jQuery script tag from header javascript.html (remains in footer) - Update package file to improve module discovery. - Improve Hugo and ESLint config for module discovery and ES6 syntax
1 parent 853e628 commit 4cfff23

23 files changed

+1544
-428
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ node_modules
1616
!telegraf-build/scripts
1717
!telegraf-build/README.md
1818
/cypress/screenshots/*
19+
/cypress/videos/*
20+
test-results.xml
1921
/influxdb3cli-build-scripts/content
2022
.vscode/*
2123
.idea

.husky/_/serve

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#!/bin/sh
2+
3+
if [ "$LEFTHOOK_VERBOSE" = "1" -o "$LEFTHOOK_VERBOSE" = "true" ]; then
4+
set -x
5+
fi
6+
7+
if [ "$LEFTHOOK" = "0" ]; then
8+
exit 0
9+
fi
10+
11+
call_lefthook()
12+
{
13+
if test -n "$LEFTHOOK_BIN"
14+
then
15+
"$LEFTHOOK_BIN" "$@"
16+
elif lefthook -h >/dev/null 2>&1
17+
then
18+
lefthook "$@"
19+
else
20+
dir="$(git rev-parse --show-toplevel)"
21+
osArch=$(uname | tr '[:upper:]' '[:lower:]')
22+
cpuArch=$(uname -m | sed 's/aarch64/arm64/;s/x86_64/x64/')
23+
if test -f "$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook"
24+
then
25+
"$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook" "$@"
26+
elif test -f "$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook"
27+
then
28+
"$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook" "$@"
29+
elif test -f "$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook"
30+
then
31+
"$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook" "$@"
32+
elif test -f "$dir/node_modules/lefthook/bin/index.js"
33+
then
34+
"$dir/node_modules/lefthook/bin/index.js" "$@"
35+
36+
elif bundle exec lefthook -h >/dev/null 2>&1
37+
then
38+
bundle exec lefthook "$@"
39+
elif yarn lefthook -h >/dev/null 2>&1
40+
then
41+
yarn lefthook "$@"
42+
elif pnpm lefthook -h >/dev/null 2>&1
43+
then
44+
pnpm lefthook "$@"
45+
elif swift package plugin lefthook >/dev/null 2>&1
46+
then
47+
swift package --disable-sandbox plugin lefthook "$@"
48+
elif command -v mint >/dev/null 2>&1
49+
then
50+
mint run csjones/lefthook-plugin "$@"
51+
else
52+
echo "Can't find lefthook in PATH"
53+
fi
54+
fi
55+
}
56+
57+
call_lefthook run "serve" "$@"

.nvmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
v23.10.0

CONTRIBUTING.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,10 @@ For the linting and tests to run, you need to install Docker and Node.js
2828
dependencies.
2929

3030
\_**Note:**
31-
We strongly recommend running linting and tests, but you can skip them
32-
(and avoid installing dependencies)
31+
The git pre-commit and pre-push hooks are configured to run linting and tests automatically
32+
when you commit or push changes.
33+
We strongly recommend letting them run, but you can skip them
34+
(and avoid installing related dependencies)
3335
by including the `--no-verify` flag with your commit--for example, enter the following command in your terminal:
3436

3537
```sh
@@ -51,7 +53,7 @@ dev dependencies used in pre-commit hooks for linting, syntax-checking, and test
5153
Dev dependencies include:
5254

5355
- [Lefthook](https://github.com/evilmartians/lefthook): configures and
54-
manages pre-commit hooks for linting and testing Markdown content.
56+
manages git pre-commit and pre-push hooks for linting and testing Markdown content.
5557
- [prettier](https://prettier.io/docs/en/): formats code, including Markdown, according to style rules for consistency
5658
- [Cypress]: e2e testing for UI elements and URLs in content
5759

@@ -93,9 +95,11 @@ Make your suggested changes being sure to follow the [style and formatting guide
9395

9496
## Lint and test your changes
9597

98+
`package.json` contains scripts for running tests and linting.
99+
96100
### Automatic pre-commit checks
97101

98-
docs-v2 uses Lefthook to manage Git hooks, such as pre-commit hooks that lint Markdown and test code blocks.
102+
docs-v2 uses Lefthook to manage Git hooks that run during pre-commit and pre-push. The hooks run the scripts defined in `package.json` to lint Markdown and test code blocks.
99103
When you try to commit changes (`git commit`), Git runs
100104
the commands configured in `lefthook.yml` which pass your **staged** files to Vale,
101105
Prettier, Cypress (for UI tests and link-checking), and Pytest (for testing Python and shell code in code blocks).

assets/js/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './main.js';

assets/js/main.js

Lines changed: 94 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@
66
/** Import modules that are not components.
77
* TODO: Refactor these into single-purpose component modules.
88
*/
9-
// import * as codeblocksPreferences from './api-libs.js';
10-
// import * as datetime from './datetime.js';
11-
// import * as featureCallouts from './feature-callouts.js';
129
import * as apiLibs from './api-libs.js';
1310
import * as codeControls from './code-controls.js';
1411
import * as contentInteractions from './content-interactions.js';
@@ -21,15 +18,6 @@ import * as pageContext from './page-context.js';
2118
import * as pageFeedback from './page-feedback.js';
2219
import * as tabbedContent from './tabbed-content.js';
2320
import * as v3Wayfinding from './v3-wayfinding.js';
24-
// import * as homeInteractions from './home-interactions.js';
25-
// import { getUrls, getReferrerHost, InfluxDBUrl } from './influxdb-url.js';
26-
// import * as keybindings from './keybindings.js';
27-
// import * as listFilters from './list-filters.js';
28-
// import { Modal } from './modal.js';
29-
// import { showNotifications } from './notifications.js';
30-
// import ReleaseTOC from './release-toc.js';
31-
// import * as scroll from './scroll.js';
32-
// import { TabbedContent } from './tabbed-content.js';
3321

3422
/** Import component modules
3523
* The component pattern organizes JavaScript, CSS, and HTML for a specific UI element or interaction:
@@ -41,40 +29,95 @@ import * as v3Wayfinding from './v3-wayfinding.js';
4129
import AskAITrigger from './ask-ai-trigger.js';
4230
import CodePlaceholder from './code-placeholders.js';
4331
import { CustomTimeTrigger } from './custom-timestamps.js';
32+
import FluxInfluxDBVersionsTrigger from './flux-influxdb-versions.js';
4433
import { SearchButton } from './search-button.js';
4534
import { SidebarToggle } from './sidebar-toggle.js';
4635
import Theme from './theme.js';
4736
import ThemeSwitch from './theme-switch.js';
48-
// import CodeControls from './code-controls.js';
49-
// import ContentInteractions from './content-interactions.js';
50-
// import CustomTimestamps from './custom-timestamps.js';
51-
// import Diagram from './Diagram.js';
52-
// import FluxGroupKeysExample from './FluxGroupKeysExample.js';
53-
import FluxInfluxDBVersionsTrigger from './flux-influxdb-versions.js';
54-
// import PageFeedback from './page-feedback.js';
55-
// import SearchInput from './SearchInput.js';
56-
// import Sidebar from './Sidebar.js';
57-
// import V3Wayfinding from './v3-wayfinding.js';
58-
// import VersionSelector from './VersionSelector.js';
59-
60-
// Expose libraries and components within a namespaced object (for backwards compatibility or testing)
61-
// Expose libraries and components within a namespaced object (for backwards compatibility or testing)
62-
6337

38+
/**
39+
* Component Registry
40+
* A central registry that maps component names to their constructor functions.
41+
* Add new components to this registry as they are created or migrated from non-component modules.
42+
* This allows for:
43+
* 1. Automatic component initialization based on data-component attributes
44+
* 2. Centralized component management
45+
* 3. Easy addition/removal of components
46+
* 4. Simplified testing and debugging
47+
*/
48+
const componentRegistry = {
49+
'ask-ai-trigger': AskAITrigger,
50+
'code-placeholder': CodePlaceholder,
51+
'custom-time-trigger': CustomTimeTrigger,
52+
'flux-influxdb-versions-trigger': FluxInfluxDBVersionsTrigger,
53+
'search-button': SearchButton,
54+
'sidebar-toggle': SidebarToggle,
55+
'theme': Theme,
56+
'theme-switch': ThemeSwitch
57+
};
6458

65-
document.addEventListener('DOMContentLoaded', function () {
59+
/**
60+
* Initialize global namespace for documentation JavaScript
61+
* Exposes core modules for debugging, testing, and backwards compatibility
62+
*/
63+
function initGlobals() {
6664
if (typeof window.influxdatadocs === 'undefined') {
6765
window.influxdatadocs = {};
6866
}
6967

70-
// Expose modules to the global object for debugging, testing, and backwards compatibility for non-ES6 modules.
68+
// Expose modules to the global object for debugging, testing, and backwards compatibility
7169
window.influxdatadocs.delay = delay;
7270
window.influxdatadocs.localStorage = window.LocalStorageAPI = localStorage;
7371
window.influxdatadocs.pageContext = pageContext;
7472
window.influxdatadocs.toggleModal = modals.toggleModal;
73+
window.influxdatadocs.componentRegistry = componentRegistry;
74+
75+
return window.influxdatadocs;
76+
}
77+
78+
/**
79+
* Initialize components based on data-component attributes
80+
* @param {Object} globals - The global influxdatadocs namespace
81+
*/
82+
function initComponents(globals) {
83+
const components = document.querySelectorAll('[data-component]');
84+
85+
components.forEach((component) => {
86+
const componentName = component.getAttribute('data-component');
87+
const ComponentConstructor = componentRegistry[componentName];
88+
89+
if (ComponentConstructor) {
90+
// Initialize the component and store its instance in the global namespace
91+
try {
92+
const instance = ComponentConstructor({ component });
93+
globals[componentName] = ComponentConstructor;
94+
95+
// Optionally store component instances for future reference
96+
if (!globals.instances) {
97+
globals.instances = {};
98+
}
99+
100+
if (!globals.instances[componentName]) {
101+
globals.instances[componentName] = [];
102+
}
103+
104+
globals.instances[componentName].push({
105+
element: component,
106+
instance
107+
});
108+
} catch (error) {
109+
console.error(`Error initializing component "${componentName}":`, error);
110+
}
111+
} else {
112+
console.warn(`Unknown component: "${componentName}"`);
113+
}
114+
});
115+
}
75116

76-
// On content loaded, initialize (not-component-ready) UI interaction modules
77-
// To differentiate these from component-ready modules, these modules typically export an initialize function that wraps UI interactions and event listeners.
117+
/**
118+
* Initialize all non-component modules
119+
*/
120+
function initModules() {
78121
modals.initialize();
79122
apiLibs.initialize();
80123
codeControls.initialize();
@@ -84,67 +127,24 @@ document.addEventListener('DOMContentLoaded', function () {
84127
pageFeedback.initialize();
85128
tabbedContent.initialize();
86129
v3Wayfinding.initialize();
130+
}
87131

88-
/** Initialize components
89-
Component Structure: Each component is structured as a jQuery anonymous function that listens for the document ready state.
90-
Initialization in main.js: Each component is called in main.js inside a jQuery document ready function to ensure they are initialized when the document is ready.
91-
Note: These components should *not* be called directly in the HTML.
92-
*/
93-
const components = document.querySelectorAll('[data-component]');
94-
components.forEach((component) => {
95-
const componentName = component.getAttribute('data-component');
96-
switch (componentName) {
97-
case 'ask-ai-trigger':
98-
AskAITrigger({ component });
99-
window.influxdatadocs[componentName] = AskAITrigger;
100-
break;
101-
case 'code-placeholder':
102-
CodePlaceholder({ component });
103-
window.influxdatadocs[componentName] = CodePlaceholder;
104-
break;
105-
case 'custom-time-trigger':
106-
CustomTimeTrigger({ component });
107-
window.influxdatadocs[componentName] = CustomTimeTrigger;
108-
break;
109-
case 'flux-influxdb-versions-trigger':
110-
FluxInfluxDBVersionsTrigger({ component });
111-
window.influxdatadocs[componentName] = FluxInfluxDBVersionsTrigger;
112-
break;
113-
case 'search-button':
114-
SearchButton({ component });
115-
window.influxdatadocs[componentName] = SearchButton;
116-
break;
117-
case 'sidebar-toggle':
118-
SidebarToggle({ component });
119-
window.influxdatadocs[componentName] = SidebarToggle;
120-
break;
121-
case 'theme':
122-
Theme({ component });
123-
window.influxdatadocs[componentName] = Theme;
124-
break;
125-
// CodeControls();
126-
// ContentInteractions();
127-
// CustomTimestamps();
128-
// Diagram();
129-
// FluxGroupKeysExample();
130-
// FluxInfluxDBVersionsModal();
131-
// InfluxDBUrl();
132-
// Modal();
133-
// PageFeedback();
134-
// ReleaseTOC();
135-
// SearchInput();
136-
// showNotifications();
137-
// Sidebar();
138-
// TabbedContent();
139-
// ThemeSwitch({});
140-
// V3Wayfinding();
141-
// VersionSelector();
142-
case 'theme-switch':
143-
ThemeSwitch({ component });
144-
window.influxdatadocs[componentName] = ThemeSwitch;
145-
break;
146-
default:
147-
console.warn(`Unknown component: ${componentName}`);
148-
}
149-
});
150-
});
132+
/**
133+
* Main initialization function
134+
*/
135+
function init() {
136+
// Initialize global namespace and expose core modules
137+
const globals = initGlobals();
138+
139+
// Initialize non-component UI modules
140+
initModules();
141+
142+
// Initialize components from registry
143+
initComponents(globals);
144+
}
145+
146+
// Initialize everything when the DOM is ready
147+
document.addEventListener('DOMContentLoaded', init);
148+
149+
// Export public API
150+
export { initGlobals, componentRegistry };

assets/jsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
"baseUrl": ".",
44
"paths": {
55
"*": [
6-
"*"
6+
"*",
7+
"../node_modules/*"
78
]
89
}
910
}

0 commit comments

Comments
 (0)