fix(influxdb3): Enterprise: update options in CLI reference:
Add options new in Beta Remove old options, add see references, add anchors for backward compat. Fix link checker test to not fail when no links exist in the articlepull/5913/head
parent
1ac88a68db
commit
db093f626c
|
@ -54,6 +54,7 @@ influxdb3 serve
|
||||||
- [object-store](#object-store)
|
- [object-store](#object-store)
|
||||||
- [data-dir](#data-dir)
|
- [data-dir](#data-dir)
|
||||||
- [node-id](#node-id)
|
- [node-id](#node-id)
|
||||||
|
- [cluster-id](#cluster-id)
|
||||||
- [mode](#mode)
|
- [mode](#mode)
|
||||||
- [license-email](#license-email)
|
- [license-email](#license-email)
|
||||||
- [query-file-limit](#query-file-limit)
|
- [query-file-limit](#query-file-limit)
|
||||||
|
@ -112,7 +113,6 @@ influxdb3 serve
|
||||||
- [Memory](#memory)
|
- [Memory](#memory)
|
||||||
- [ram-pool-data-bytes](#ram-pool-data-bytes)
|
- [ram-pool-data-bytes](#ram-pool-data-bytes)
|
||||||
- [exec-mem-pool-bytes](#exec-mem-pool-bytes)
|
- [exec-mem-pool-bytes](#exec-mem-pool-bytes)
|
||||||
- [buffer-mem-limit-mb](#buffer-mem-limit-mb)
|
|
||||||
- [force-snapshot-mem-threshold](#force-snapshot-mem-threshold)
|
- [force-snapshot-mem-threshold](#force-snapshot-mem-threshold)
|
||||||
- [Write-Ahead Log (WAL)](#write-ahead-log-wal)
|
- [Write-Ahead Log (WAL)](#write-ahead-log-wal)
|
||||||
- [wal-flush-interval](#wal-flush-interval)
|
- [wal-flush-interval](#wal-flush-interval)
|
||||||
|
@ -123,9 +123,6 @@ influxdb3 serve
|
||||||
- [read-from-node-ids](#read-from-node-ids)
|
- [read-from-node-ids](#read-from-node-ids)
|
||||||
- [replication-interval](#replication-interval)
|
- [replication-interval](#replication-interval)
|
||||||
- [Compaction](#compaction)
|
- [Compaction](#compaction)
|
||||||
- [compactor-id](#compactor-id)
|
|
||||||
- [compact-from-node-ids](#compact-from-node-ids)
|
|
||||||
- [run-compactions](#run-compactions)
|
|
||||||
- [compaction-row-limit](#compaction-row-limit)
|
- [compaction-row-limit](#compaction-row-limit)
|
||||||
- [compaction-max-num-files-per-plan](#compaction-max-num-files-per-plan)
|
- [compaction-max-num-files-per-plan](#compaction-max-num-files-per-plan)
|
||||||
- [compaction-gen2-duration](#compaction-gen2-duration)
|
- [compaction-gen2-duration](#compaction-gen2-duration)
|
||||||
|
@ -133,7 +130,7 @@ influxdb3 serve
|
||||||
- [gen1-duration](#gen1-duration)
|
- [gen1-duration](#gen1-duration)
|
||||||
- [Caching](#caching)
|
- [Caching](#caching)
|
||||||
- [preemptive-cache-age](#preemptive-cache-age)
|
- [preemptive-cache-age](#preemptive-cache-age)
|
||||||
- [parquet-mem-cache-size-mb](#parquet-mem-cache-size-mb)
|
- [parquet-mem-cache-size](#parquet-mem-cache-size)
|
||||||
- [parquet-mem-cache-prune-percentage](#parquet-mem-cache-prune-percentage)
|
- [parquet-mem-cache-prune-percentage](#parquet-mem-cache-prune-percentage)
|
||||||
- [parquet-mem-cache-prune-interval](#parquet-mem-cache-prune-interval)
|
- [parquet-mem-cache-prune-interval](#parquet-mem-cache-prune-interval)
|
||||||
- [disable-parquet-mem-cache](#disable-parquet-mem-cache)
|
- [disable-parquet-mem-cache](#disable-parquet-mem-cache)
|
||||||
|
@ -153,6 +150,7 @@ influxdb3 serve
|
||||||
- [bucket](#bucket)
|
- [bucket](#bucket)
|
||||||
- [data-dir](#data-dir)
|
- [data-dir](#data-dir)
|
||||||
- [node-id](#node-id)
|
- [node-id](#node-id)
|
||||||
|
- [cluster-id](#cluster-id)
|
||||||
- [mode](#mode)
|
- [mode](#mode)
|
||||||
- [license-email](#license-email)
|
- [license-email](#license-email)
|
||||||
- [query-file-limit](#query-file-limit)
|
- [query-file-limit](#query-file-limit)
|
||||||
|
@ -162,12 +160,12 @@ influxdb3 serve
|
||||||
Specifies which object storage to use to store Parquet files.
|
Specifies which object storage to use to store Parquet files.
|
||||||
This option supports the following values:
|
This option supports the following values:
|
||||||
|
|
||||||
- `memory` _(default)_
|
- `memory` _(default)_: Effectively no object persistence
|
||||||
- `memory-throttled`
|
- `memory-throttled`: Like `memory` but with latency and throughput that somewhat resembles a cloud object store
|
||||||
- `file`
|
- `file`: Stores objects in the local filesystem (must also set `--data-dir`)
|
||||||
- `s3`
|
- `s3`: Amazon S3 (must also set `--bucket`, `--aws-access-key-id`, `--aws-secret-access-key`, and possibly `--aws-default-region`)
|
||||||
- `google`
|
- `google`: Google Cloud Storage (must also set `--bucket` and `--google-service-account`)
|
||||||
- `azure`
|
- `azure`: Microsoft Azure blob storage (must also set `--bucket`, `--azure-storage-account`, and `--azure-storage-access-key`)
|
||||||
|
|
||||||
| influxdb3 serve option | Environment variable |
|
| influxdb3 serve option | Environment variable |
|
||||||
| :--------------------- | :----------------------- |
|
| :--------------------- | :----------------------- |
|
||||||
|
@ -197,17 +195,30 @@ configuration--for example, the same bucket.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
#### cluster-id
|
||||||
|
|
||||||
|
Specifies the cluster identifier that prefixes the object store path for the Enterprise Catalog.
|
||||||
|
This value must be different than the [`--node-id`](#node-id) value.
|
||||||
|
|
||||||
|
| influxdb3 serve option | Environment variable |
|
||||||
|
| :--------------------- | :--------------------------------- |
|
||||||
|
| `--cluster-id` | `INFLUXDB3_ENTERPRISE_CLUSTER_ID` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
#### mode
|
#### mode
|
||||||
|
|
||||||
Sets the mode to start the server in.
|
Sets the mode to start the server in.
|
||||||
|
|
||||||
This option supports the following values:
|
This option supports the following values:
|
||||||
|
|
||||||
- `read`
|
- `all` _(default)_
|
||||||
- `read_write` _(default)_
|
- `ingest`
|
||||||
- `compactor`
|
- `query`
|
||||||
|
- `compact`
|
||||||
|
- `process`
|
||||||
|
|
||||||
**Default:** `read_write`
|
**Default:** `all`
|
||||||
|
|
||||||
| influxdb3 serve option | Environment variable |
|
| influxdb3 serve option | Environment variable |
|
||||||
| :--------------------- | :-------------------------- |
|
| :--------------------- | :-------------------------- |
|
||||||
|
@ -844,9 +855,10 @@ Specifies the size of the RAM cache used to store data, in bytes.
|
||||||
|
|
||||||
#### exec-mem-pool-bytes
|
#### exec-mem-pool-bytes
|
||||||
|
|
||||||
Specifies the size of the memory pool used during query execution, in bytes.
|
Specifies the size of memory pool used during query execution.
|
||||||
|
Can be given as absolute value in bytes or as a percentage of the total available memory (for example: `10%`).
|
||||||
|
|
||||||
**Default:** `8589934592`
|
**Default:** `20%`
|
||||||
|
|
||||||
| influxdb3 serve option | Environment variable |
|
| influxdb3 serve option | Environment variable |
|
||||||
| :---------------------- | :------------------------------ |
|
| :---------------------- | :------------------------------ |
|
||||||
|
@ -854,26 +866,14 @@ Specifies the size of the memory pool used during query execution, in bytes.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
#### buffer-mem-limit-mb
|
|
||||||
|
|
||||||
Specifies the size limit of the buffered data in MB. If this limit is exceeded,
|
|
||||||
the server forces a snapshot.
|
|
||||||
|
|
||||||
**Default:** `5000`
|
|
||||||
|
|
||||||
| influxdb3 serve option | Environment variable |
|
|
||||||
| :---------------------- | :------------------------------ |
|
|
||||||
| `--buffer-mem-limit-mb` | `INFLUXDB3_BUFFER_MEM_LIMIT_MB` |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
#### force-snapshot-mem-threshold
|
#### force-snapshot-mem-threshold
|
||||||
|
<span id="buffer-mem-limit-mb" />
|
||||||
|
|
||||||
Specifies the threshold for the internal memory buffer. Supports either a
|
Specifies the threshold for the internal memory buffer. Supports either a
|
||||||
percentage (portion of available memory)of or absolute value
|
percentage (portion of available memory) or absolute value in MB
|
||||||
(total bytes)--for example: `70%` or `100000`.
|
(total bytes)--for example: `70%` or `1000 MB`.
|
||||||
|
|
||||||
**Default:** `70%`
|
**Default:** `50%`
|
||||||
|
|
||||||
| influxdb3 serve option | Environment variable |
|
| influxdb3 serve option | Environment variable |
|
||||||
| :------------------------------- | :--------------------------------------- |
|
| :------------------------------- | :--------------------------------------- |
|
||||||
|
@ -972,47 +972,31 @@ Defines the interval at which each replica specified in the
|
||||||
|
|
||||||
### Compaction
|
### Compaction
|
||||||
|
|
||||||
- [compactor-id](#compactor-id)
|
|
||||||
- [compact-from-node-ids](#compact-from-node-ids)
|
|
||||||
- [run-compactions](#run-compactions)
|
|
||||||
- [compaction-row-limit](#compaction-row-limit)
|
- [compaction-row-limit](#compaction-row-limit)
|
||||||
- [compaction-max-num-files-per-plan](#compaction-max-num-files-per-plan)
|
- [compaction-max-num-files-per-plan](#compaction-max-num-files-per-plan)
|
||||||
- [compaction-gen2-duration](#compaction-gen2-duration)
|
- [compaction-gen2-duration](#compaction-gen2-duration)
|
||||||
- [compaction-multipliers](#compaction-multipliers)
|
- [compaction-multipliers](#compaction-multipliers)
|
||||||
|
- [compaction-cleanup-wait](#compaction-cleanup-wait)
|
||||||
- [gen1-duration](#gen1-duration)
|
- [gen1-duration](#gen1-duration)
|
||||||
|
|
||||||
#### compactor-id
|
#### compactor-id
|
||||||
|
|
||||||
Specifies the prefix in the object store where all compacted data is written.
|
> [!Important]
|
||||||
Provide this option only if this server should handle compaction for its own
|
> This option has been superseded by using `--mode compact`. See the [mode](#mode) section for details.
|
||||||
write buffer and any replicas it manages.
|
|
||||||
|
|
||||||
| influxdb3 serve option | Environment variable |
|
|
||||||
| :--------------------- | :---------------------------------- |
|
|
||||||
| `--compactor-id` | `INFLUXDB3_ENTERPRISE_COMPACTOR_ID` |
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
#### compact-from-node-ids
|
#### compact-from-node-ids
|
||||||
|
|
||||||
Defines a comma-separated list of writer identifier prefixes from which data is
|
> [!Important]
|
||||||
compacted.
|
> This option has been superseded by using `--mode compact`. See the [mode](#mode) section for details.
|
||||||
|
|
||||||
| influxdb3 serve option | Environment variable |
|
|
||||||
| :-------------------------- | :--------------------------------------------- |
|
|
||||||
| `--compact-from-node-ids` | `INFLUXDB3_ENTERPRISE_COMPACT_FROM_WRITER_IDS` |
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
#### run-compactions
|
#### run-compactions
|
||||||
|
|
||||||
Indicates that the server should run compactions. Only a single server should
|
> [!Important]
|
||||||
run compactions for a given `compactor-id`. This option is only applicable if a
|
> This option has been superseded by using `--mode compact`. See the [mode](#mode) section for details.
|
||||||
`compactor-id` is set.
|
|
||||||
|
|
||||||
| influxdb3 serve option | Environment variable |
|
|
||||||
| :--------------------- | :------------------------------------- |
|
|
||||||
| `--run-compactions` | `INFLUXDB3_ENTERPRISE_RUN_COMPACTIONS` |
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -1070,6 +1054,19 @@ compaction levels. The first element specifies the duration of the first level
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
#### compaction-cleanup-wait
|
||||||
|
|
||||||
|
Specifies the amount of time that the compactor waits after finishing a compaction run
|
||||||
|
to delete files marked as needing deletion during that compaction run.
|
||||||
|
|
||||||
|
**Default:** `10m`
|
||||||
|
|
||||||
|
| influxdb3 serve option | Environment variable |
|
||||||
|
| :-------------------------- | :--------------------------------------------- |
|
||||||
|
| `--compaction-cleanup-wait` | `INFLUXDB3_ENTERPRISE_COMPACTION_CLEANUP_WAIT` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
#### gen1-duration
|
#### gen1-duration
|
||||||
|
|
||||||
Specifies the duration that Parquet files are arranged into. Data timestamps
|
Specifies the duration that Parquet files are arranged into. Data timestamps
|
||||||
|
@ -1088,7 +1085,7 @@ compactor can merge into larger generations.
|
||||||
### Caching
|
### Caching
|
||||||
|
|
||||||
- [preemptive-cache-age](#preemptive-cache-age)
|
- [preemptive-cache-age](#preemptive-cache-age)
|
||||||
- [parquet-mem-cache-size-mb](#parquet-mem-cache-size-mb)
|
- [parquet-mem-cache-size](#parquet-mem-cache-size)
|
||||||
- [parquet-mem-cache-prune-percentage](#parquet-mem-cache-prune-percentage)
|
- [parquet-mem-cache-prune-percentage](#parquet-mem-cache-prune-percentage)
|
||||||
- [parquet-mem-cache-prune-interval](#parquet-mem-cache-prune-interval)
|
- [parquet-mem-cache-prune-interval](#parquet-mem-cache-prune-interval)
|
||||||
- [disable-parquet-mem-cache](#disable-parquet-mem-cache)
|
- [disable-parquet-mem-cache](#disable-parquet-mem-cache)
|
||||||
|
@ -1108,17 +1105,16 @@ Specifies the interval to prefetch into the Parquet cache during compaction.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
#### parquet-mem-cache-size-mb
|
#### parquet-mem-cache-size
|
||||||
|
<span id="parquet-mem-cache-size-mb" />
|
||||||
|
|
||||||
Defines the size of the in-memory Parquet cache in megabytes (MB).
|
Specifies the size of the in-memory Parquet cache in megabytes or percentage of total available memory.
|
||||||
|
|
||||||
**Default:** `1000`
|
**Default:** `20%`
|
||||||
|
|
||||||
| influxdb3 serve option | Environment variable |
|
| influxdb3 serve option | Environment variable |
|
||||||
| :---------------------------- | :------------------------------------ |
|
| :-------------------------- | :---------------------------------- |
|
||||||
| `--parquet-mem-cache-size-mb` | `INFLUXDB3_PARQUET_MEM_CACHE_SIZE_MB` |
|
| `--parquet-mem-cache-size` | `INFLUXDB3_PARQUET_MEM_CACHE_SIZE` |
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
#### parquet-mem-cache-prune-percentage
|
#### parquet-mem-cache-prune-percentage
|
||||||
|
|
||||||
|
@ -1225,7 +1221,12 @@ engine uses.
|
||||||
|
|
||||||
Specifies the Python package manager that the processing engine uses.
|
Specifies the Python package manager that the processing engine uses.
|
||||||
|
|
||||||
**Default:** `10s`
|
This option supports the following values:
|
||||||
|
- `discover` _(default)_: Automatically discover available package manager
|
||||||
|
- `pip`: Use pip package manager
|
||||||
|
- `uv`: Use uv package manager
|
||||||
|
|
||||||
|
**Default:** `discover`
|
||||||
|
|
||||||
| influxdb3 serve option | Environment variable |
|
| influxdb3 serve option | Environment variable |
|
||||||
| :--------------------- | :------------------- |
|
| :--------------------- | :------------------- |
|
||||||
|
|
|
@ -9,23 +9,34 @@ describe('Article links', () => {
|
||||||
function isDownloadLink(href) {
|
function isDownloadLink(href) {
|
||||||
// Check for common download file extensions
|
// Check for common download file extensions
|
||||||
const downloadExtensions = [
|
const downloadExtensions = [
|
||||||
'.pdf', '.zip', '.tar.gz', '.tgz', '.rar', '.exe', '.dmg', '.pkg',
|
'.pdf',
|
||||||
'.deb', '.rpm', '.xlsx', '.csv', '.doc', '.docx', '.ppt', '.pptx'
|
'.zip',
|
||||||
|
'.tar.gz',
|
||||||
|
'.tgz',
|
||||||
|
'.rar',
|
||||||
|
'.exe',
|
||||||
|
'.dmg',
|
||||||
|
'.pkg',
|
||||||
|
'.deb',
|
||||||
|
'.rpm',
|
||||||
|
'.xlsx',
|
||||||
|
'.csv',
|
||||||
|
'.doc',
|
||||||
|
'.docx',
|
||||||
|
'.ppt',
|
||||||
|
'.pptx',
|
||||||
];
|
];
|
||||||
|
|
||||||
// Check for download domains or paths
|
// Check for download domains or paths
|
||||||
const downloadDomains = [
|
const downloadDomains = ['dl.influxdata.com', 'downloads.influxdata.com'];
|
||||||
'dl.influxdata.com',
|
|
||||||
'downloads.influxdata.com'
|
|
||||||
];
|
|
||||||
|
|
||||||
// Check if URL contains a download extension
|
// Check if URL contains a download extension
|
||||||
const hasDownloadExtension = downloadExtensions.some(ext =>
|
const hasDownloadExtension = downloadExtensions.some((ext) =>
|
||||||
href.toLowerCase().endsWith(ext)
|
href.toLowerCase().endsWith(ext)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Check if URL is from a download domain
|
// Check if URL is from a download domain
|
||||||
const isFromDownloadDomain = downloadDomains.some(domain =>
|
const isFromDownloadDomain = downloadDomains.some((domain) =>
|
||||||
href.toLowerCase().includes(domain)
|
href.toLowerCase().includes(domain)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -40,19 +51,31 @@ describe('Article links', () => {
|
||||||
cy.request({
|
cy.request({
|
||||||
method: 'HEAD',
|
method: 'HEAD',
|
||||||
url: href,
|
url: href,
|
||||||
failOnStatusCode: false,
|
}).then((response) => {
|
||||||
timeout: 10000 // 10 second timeout for download links
|
const message = `Link is broken: ${href} (status: ${response.status})`;
|
||||||
}).then(response => {
|
try {
|
||||||
expect(response.status).to.be.lt(400);
|
expect(response.status).to.be.lt(400);
|
||||||
|
} catch (e) {
|
||||||
|
// Log the broken link with the URL for better visibility in reports
|
||||||
|
cy.log(`❌ BROKEN LINK: ${href} (${response.status})`);
|
||||||
|
throw new Error(message);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
cy.log(`** Testing link: ${href} **`);
|
cy.log(`** Testing link: ${href} **`);
|
||||||
cy.request({
|
cy.request({
|
||||||
url: href,
|
url: href,
|
||||||
failOnStatusCode: false,
|
failOnStatusCode: false,
|
||||||
timeout: 30000 // 30 second timeout for regular links
|
timeout: 10000, // 10 second timeout for regular links
|
||||||
}).then(response => {
|
}).then((response) => {
|
||||||
|
const message = `Link is broken: ${href} (status: ${response.status})`;
|
||||||
|
try {
|
||||||
expect(response.status).to.be.lt(400);
|
expect(response.status).to.be.lt(400);
|
||||||
|
} catch (e) {
|
||||||
|
// Log the broken link with the URL for better visibility in reports
|
||||||
|
cy.log(`❌ BROKEN LINK: ${href} (${response.status})`);
|
||||||
|
throw new Error(message);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,14 +83,21 @@ describe('Article links', () => {
|
||||||
subjects.forEach((subject) => {
|
subjects.forEach((subject) => {
|
||||||
it(`contains valid internal links on ${subject}`, function () {
|
it(`contains valid internal links on ${subject}`, function () {
|
||||||
cy.visit(`${subject}`);
|
cy.visit(`${subject}`);
|
||||||
|
// Test internal links
|
||||||
// Test internal links (including anchor links)
|
// 1. Timeout and fail the test if article is not found
|
||||||
cy.get('article a[href^="/"]').each(($a) => {
|
// 2. Check each link.
|
||||||
const href = $a.attr('href');
|
// 3. If no links are found, continue without failing
|
||||||
// Skip links that contain "kapa.ai"
|
cy.get('article').then(($article) => {
|
||||||
if (!href.includes('kapa.ai')) {
|
// Find links without failing the test if none are found
|
||||||
testLink(href);
|
const $links = $article.find('a[href^="/"]');
|
||||||
|
if ($links.length === 0) {
|
||||||
|
cy.log('No internal links found on this page');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
cy.wrap($links).each(($a) => {
|
||||||
|
const href = $a.attr('href');
|
||||||
|
testLink(href);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -78,9 +108,16 @@ describe('Article links', () => {
|
||||||
const missingAnchors = [];
|
const missingAnchors = [];
|
||||||
|
|
||||||
// Process anchor links individually
|
// Process anchor links individually
|
||||||
cy.get('article a[href^="#"]').each(($a) => {
|
cy.get('article').then(($article) => {
|
||||||
const href = $a.prop('href'); // Use prop() instead of attr()
|
const $anchorLinks = $article.find('a[href^="#"]');
|
||||||
if (href && href.length > 1) { // Skip empty anchors (#)
|
if ($anchorLinks.length === 0) {
|
||||||
|
cy.log('No anchor links found on this page');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cy.wrap($anchorLinks).each(($a) => {
|
||||||
|
const href = $a.prop('href');
|
||||||
|
if (href && href.length > 1) {
|
||||||
|
// Skip empty anchors (#)
|
||||||
// Get just the fragment part
|
// Get just the fragment part
|
||||||
const url = new URL(href);
|
const url = new URL(href);
|
||||||
const anchorId = url.hash.substring(1); // Remove the # character
|
const anchorId = url.hash.substring(1); // Remove the # character
|
||||||
|
@ -91,7 +128,7 @@ describe('Article links', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use DOM to check if the element exists, but don't fail if missing
|
// Use DOM to check if the element exists, but don't fail if missing
|
||||||
cy.window().then(win => {
|
cy.window().then((win) => {
|
||||||
const element = win.document.getElementById(anchorId);
|
const element = win.document.getElementById(anchorId);
|
||||||
if (element) {
|
if (element) {
|
||||||
cy.log(`✅ Anchor target exists: #${anchorId}`);
|
cy.log(`✅ Anchor target exists: #${anchorId}`);
|
||||||
|
@ -102,10 +139,13 @@ describe('Article links', () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}).then(() => {
|
})
|
||||||
|
.then(() => {
|
||||||
// After checking all anchors, log a summary
|
// After checking all anchors, log a summary
|
||||||
if (missingAnchors.length > 0) {
|
if (missingAnchors.length > 0) {
|
||||||
cy.log(`⚠️ Found ${missingAnchors.length} missing anchor targets: ${missingAnchors.join(', ')}`);
|
cy.log(
|
||||||
|
`⚠️ Found ${missingAnchors.length} missing anchor targets: ${missingAnchors.join(', ')}`
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
cy.log('✅ All anchor targets are valid');
|
cy.log('✅ All anchor targets are valid');
|
||||||
}
|
}
|
||||||
|
@ -114,12 +154,23 @@ describe('Article links', () => {
|
||||||
|
|
||||||
it(`contains valid external links on ${subject}`, function () {
|
it(`contains valid external links on ${subject}`, function () {
|
||||||
cy.visit(`${subject}`);
|
cy.visit(`${subject}`);
|
||||||
|
|
||||||
// Test external links
|
// Test external links
|
||||||
cy.get('article a[href^="http"]').each(($a) => {
|
// 1. Timeout and fail the test if article is not found
|
||||||
|
// 2. Check each link.
|
||||||
|
// 3. If no links are found, continue without failing
|
||||||
|
cy.get('article').then(($article) => {
|
||||||
|
// Find links without failing the test if none are found
|
||||||
|
const $links = $article.find('a[href^="http"]');
|
||||||
|
if ($links.length === 0) {
|
||||||
|
cy.log('No external links found on this page');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cy.wrap($links).each(($a) => {
|
||||||
const href = $a.attr('href');
|
const href = $a.attr('href');
|
||||||
testLink(href);
|
testLink(href);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
Loading…
Reference in New Issue