Skip to content

Commit f7acce8

Browse files
authored
Merge pull request #5816 from influxdata/e2e-link-testing
chore(e2e): Add Cypress for link checking and end-to-end tests. Fix b…
2 parents b678215 + 76915fd commit f7acce8

10 files changed

+2548
-85
lines changed

cypress.config.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
const { defineConfig } = require('cypress');
2+
3+
module.exports = defineConfig({
4+
e2e: {
5+
// Automatically prefix cy.visit() and cy.request() commands with a baseUrl.
6+
baseUrl: 'http://localhost:1313',
7+
projectId: 'influxdata-docs',
8+
setupNodeEvents(on, config) {
9+
// implement node event listeners here
10+
on('task', {
11+
// Fetch the product list configured in /data/products.yml
12+
getData(filename) {
13+
return new Promise((resolve, reject) => {
14+
const yq = require('js-yaml');
15+
const fs = require('fs');
16+
const cwd = process.cwd();
17+
try {
18+
resolve(
19+
yq.load(fs.readFileSync(`${cwd}/data/${filename}.yml`, 'utf8'))
20+
);
21+
} catch (e) {
22+
reject(e);
23+
}
24+
});
25+
},
26+
});
27+
},
28+
},
29+
});

cypress/e2e/article-links.cy.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/// <reference types="cypress" />
2+
describe('Article links', () => {
3+
const subjects = Cypress.env('test_subjects').split(',');
4+
5+
subjects.forEach((subject) => {
6+
it('contains valid internal links', function () {
7+
cy.visit(`${subject}`);
8+
cy.get('article a[href^="/"]') //.filter('[href^="/"]')
9+
.each(($a) => {
10+
cy.log(`** Testing internal link ${$a.attr('href')} **`);
11+
// cy.request doesn't show in your browser's Developer Tools
12+
// because the request comes from Node, not from the browser.
13+
cy.request($a.attr('href')).its('status').should('eq', 200);
14+
});
15+
});
16+
it('contains valid external links', function () {
17+
cy.visit(`${subject}`);
18+
cy.get('article a[href^="http"]')
19+
.each(($a) => {
20+
// cy.request doesn't show in your browser's Developer Tools
21+
cy.log(`** Testing external link ${$a.attr('href')} **`);
22+
// because the request comes from Node, not from the browser.
23+
cy.request($a.attr('href')).its('status').should('eq', 200);
24+
});
25+
});
26+
});
27+
});

cypress/e2e/index.cy.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/// <reference types="cypress" />
2+
3+
describe('Docs home', function() {
4+
beforeEach(() => cy.visit('/'));
5+
6+
it('has metadata', function() {
7+
cy.title().should('eq', 'InfluxData Documentation');
8+
});
9+
10+
it('can search with mispellings', function() {
11+
cy.get('.sidebar--search').within(() => {
12+
cy.get('input#algolia-search-input').type('sql uery');
13+
cy.get('#algolia-autocomplete-listbox-0')
14+
.should('contain', 'Basic query examples')
15+
cy.get('input#algolia-search-input')
16+
.type('{esc}')
17+
cy.get('#algolia-autocomplete-listbox-0')
18+
.should('not.be.visible');
19+
});
20+
});
21+
22+
it('main heading', function() {
23+
cy.get('h1').should('contain', 'InfluxData Documentation');
24+
});
25+
26+
it('content has links to all products', function() {
27+
cy.task('getData', 'products').then((productData) => {
28+
Object.values(productData).forEach((p) => {
29+
let name = p.altname?.length > p.name.length ? p.altname : p.name;
30+
name = name.replace(/\((.*)\)/, '$1');
31+
cy.get('.home-content a').filter(`:contains(${name})`).first().click();
32+
const urlFrag = p.latest.replace(/(v\d+)\.\w+/, '$1');
33+
cy.url().should('include', urlFrag);
34+
cy.go('back');
35+
});
36+
});
37+
});
38+
});
39+

cypress/e2e/topnav.cy.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
describe('global top navigation', function () {
2+
beforeEach(function () {
3+
// Visit the Docs home page
4+
cy.visit('/');
5+
cy.get('.notification').filter(':visible').find('.close-notification').click({ force: true });
6+
});
7+
8+
describe('theme switcher', function () {
9+
it('switches light to dark', function () {
10+
// Default is light theme
11+
cy.get('body.home').should('have.css', 'background-color', 'rgb(243, 244, 251)');
12+
cy.get('#theme-switch-dark').click();
13+
cy.get('body.home').should('have.css', 'background-color', 'rgb(7, 7, 14)');
14+
cy.get('#theme-switch-light').click();
15+
cy.get('body.home').should('have.css', 'background-color', 'rgb(243, 244, 251)');
16+
});
17+
});
18+
19+
describe('product dropdown', function () {
20+
it('has links to all products', function () {
21+
cy.get('#product-dropdown .selected').contains('Select product').click({ force: true });
22+
cy.task('getData', 'products').then((productData) => {
23+
Object.values(productData).forEach((p) => {
24+
cy.get('#dropdown-items a').should('be.visible');
25+
let name = p.altname?.length > p.name.length ? p.altname : p.name;
26+
name = name.replace(/\((.*)\)/, '$1');
27+
cy.get('#dropdown-items a')
28+
.filter(`:contains(${name})`)
29+
.first()
30+
.click();
31+
const urlFrag = p.latest.replace(/(v\d+)\.\w+/, '$1');
32+
cy.url().should('include', urlFrag);
33+
// Test that the selected option is for the current product.
34+
// Reopen the dropdown.
35+
cy.get('#product-dropdown .selected').contains(name).click({ force: true });
36+
});
37+
});
38+
});
39+
});
40+
});
421 KB
Loading
476 KB
Loading

cypress/support/commands.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// ***********************************************
2+
// This example commands.js shows you how to
3+
// create various custom commands and overwrite
4+
// existing commands.
5+
//
6+
// For more comprehensive examples of custom
7+
// commands please read more here:
8+
// https://on.cypress.io/custom-commands
9+
// ***********************************************
10+
//
11+
//
12+
// -- This is a parent command --
13+
// Cypress.Commands.add('login', (email, password) => { ... })
14+
//
15+
//
16+
// -- This is a child command --
17+
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
18+
//
19+
//
20+
// -- This is a dual command --
21+
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
22+
//
23+
//
24+
// -- This will overwrite an existing command --
25+
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })

cypress/support/e2e.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// ***********************************************************
2+
// This example support/e2e.js is processed and
3+
// loaded automatically before your test files.
4+
//
5+
// This is a great place to put global configuration and
6+
// behavior that modifies Cypress.
7+
//
8+
// You can change the location of this file or turn off
9+
// automatically serving support files with the
10+
// 'supportFile' configuration option.
11+
//
12+
// You can read more here:
13+
// https://on.cypress.io/configuration
14+
// ***********************************************************
15+
16+
// Import commands.js using ES2015 syntax:
17+
import './commands'

package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
"autoprefixer": ">=10.2.5",
1212
"eslint": "^9.18.0",
1313
"globals": "^15.14.0",
14+
"cypress": "^14.0.1",
1415
"hugo-extended": ">=0.101.0",
16+
"nightwatch": "^3.11.0",
1517
"postcss": ">=8.4.31",
1618
"postcss-cli": ">=9.1.0",
1719
"prettier": "^3.2.5",
@@ -27,6 +29,10 @@
2729
"vanillajs-datepicker": "^1.3.4"
2830
},
2931
"scripts": {
32+
"e2e:chrome": "npx cypress run --browser chrome",
33+
"e2e:o": "npx cypress open",
34+
"e2e:o:links": "export cypress_test_subjects=\"http://localhost:1313/influxdb3/core/,http://localhost:1313/influxdb3/enterprise/\"; npx cypress open cypress/e2e/article-links.cy.js",
35+
"e2e:links": "export cypress_test_subjects=\"http://localhost:1313/influxdb3/core/,http://localhost:1313/influxdb3/enterprise/\"; npx cypress run --spec cypress/e2e/article-links.cy.js",
3036
"lint": "LEFTHOOK_EXCLUDE=test lefthook run pre-commit && lefthook run pre-push",
3137
"pre-commit": "lefthook run pre-commit",
3238
"test-content": "docker compose --profile test up"

0 commit comments

Comments
 (0)