Compare commits

..

8 Commits

Author SHA1 Message Date
dependabot[bot]
0f46337710 Bump the dev-patch-updates group across 1 directory with 3 updates
Bumps the dev-patch-updates group with 3 updates in the /frontend directory: [@biomejs/biome](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome), [@testing-library/react](https://github.com/testing-library/react-testing-library) and [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest).


Updates `@biomejs/biome` from 2.3.2 to 2.3.13
- [Release notes](https://github.com/biomejs/biome/releases)
- [Changelog](https://github.com/biomejs/biome/blob/main/packages/@biomejs/biome/CHANGELOG.md)
- [Commits](https://github.com/biomejs/biome/commits/@biomejs/biome@2.3.13/packages/@biomejs/biome)

Updates `@testing-library/react` from 16.3.0 to 16.3.2
- [Release notes](https://github.com/testing-library/react-testing-library/releases)
- [Changelog](https://github.com/testing-library/react-testing-library/blob/main/CHANGELOG.md)
- [Commits](https://github.com/testing-library/react-testing-library/compare/v16.3.0...v16.3.2)

Updates `vitest` from 4.0.6 to 4.0.18
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.18/packages/vitest)

---
updated-dependencies:
- dependency-name: "@biomejs/biome"
  dependency-version: 2.3.13
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@testing-library/react"
  dependency-version: 16.3.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: vitest
  dependency-version: 4.0.18
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-27 11:42:25 +00:00
Jamie Curnow
8ea8286cec More cypress fixes 2026-01-27 14:02:23 +10:00
Jamie Curnow
7ca48f876b Ugh cypress changed their exec result format. 2026-01-27 11:55:54 +10:00
Jamie Curnow
7c3c59c79f Fix cypress logger 2026-01-27 11:41:12 +10:00
Jamie Curnow
ef7f444404 Update docker image to match js version 2026-01-27 11:27:21 +10:00
Jamie Curnow
f509e0bdba Missing export 2026-01-27 11:26:54 +10:00
Jamie Curnow
9b7af474bb Cypress ... 2026-01-27 11:22:16 +10:00
Jamie Curnow
28982b8bc2 Updated config files for cypress 2026-01-27 10:46:30 +10:00
12 changed files with 113 additions and 70 deletions

View File

@@ -109,7 +109,7 @@ services:
- "cypress_logs:/test/results"
- "./dev/resolv.conf:/etc/resolv.conf:ro"
- "/etc/localtime:/etc/localtime:ro"
command: cypress run --browser chrome --config-file=cypress/config/ci.js
command: cypress run --browser chrome --config-file=cypress/config/ci.mjs
networks:
- fulltest

View File

@@ -192,7 +192,7 @@ services:
- "../test/results:/results"
- "./dev/resolv.conf:/etc/resolv.conf:ro"
- "/etc/localtime:/etc/localtime:ro"
command: cypress run --browser chrome --config-file=cypress/config/ci.js
command: cypress run --browser chrome --config-file=cypress/config/ci.mjs
networks:
- nginx_proxy_manager

View File

@@ -1,4 +1,4 @@
FROM cypress/included:14.0.1
FROM cypress/included:15.9.0
# Disable Cypress CLI colors
ENV FORCE_COLOR=0

View File

@@ -24,10 +24,10 @@ describe('Streams', () => {
// Create a custom cert pair
cy.exec('mkcert -cert-file=/test/cypress/fixtures/website1.pem -key-file=/test/cypress/fixtures/website1.key.pem website1.example.com').then((result) => {
expect(result.code).to.eq(0);
expect(result.exitCode).to.eq(0);
// Install CA
cy.exec('mkcert -install').then((result) => {
expect(result.code).to.eq(0);
expect(result.exitCode).to.eq(0);
});
});
@@ -56,7 +56,7 @@ describe('Streams', () => {
expect(data).to.have.property('udp_forwarding', false);
cy.exec('curl --noproxy -- http://website1.example.com:1500').then((result) => {
expect(result.code).to.eq(0);
expect(result.exitCode).to.eq(0);
expect(result.stdout).to.contain('yay it works');
});
});
@@ -107,7 +107,7 @@ describe('Streams', () => {
expect(data).to.have.property('udp_forwarding', true);
cy.exec('curl --noproxy -- http://website1.example.com:1502').then((result) => {
expect(result.code).to.eq(0);
expect(result.exitCode).to.eq(0);
expect(result.stdout).to.contain('yay it works');
});
});
@@ -176,6 +176,7 @@ describe('Streams', () => {
'cert_chain_of_trust',
'cert_extlifeSpan',
'cert_revocation',
'engine_problem',
'overall_grade',
];

View File

@@ -1,9 +1,9 @@
const logger = require('./logger');
const axios = require('axios').default;
import axios from "axios";
import logger from "./logger.mjs";
const BackendApi = function(config, token) {
const BackendApi = function (config, token) {
this.config = config;
this.token = token;
this.token = token;
this.axios = axios.create({
baseURL: config.baseUrl,
@@ -14,26 +14,24 @@ const BackendApi = function(config, token) {
/**
* @param {string} token
*/
BackendApi.prototype.setToken = function(token) {
BackendApi.prototype.setToken = function (token) {
this.token = token;
};
/**
* @param {bool} returnOnError
*/
BackendApi.prototype._prepareOptions = function(returnOnError) {
let options = {
BackendApi.prototype._prepareOptions = function (returnOnError) {
const options = {
headers: {
Accept: 'application/json'
}
}
Accept: "application/json",
},
};
if (this.token) {
options.headers.Authorization = 'Bearer ' + this.token;
options.headers.Authorization = `Bearer ${this.token}`;
}
if (returnOnError) {
options.validateStatus = function () {
return true;
}
options.validateStatus = () => true;
}
return options;
};
@@ -44,13 +42,30 @@ BackendApi.prototype._prepareOptions = function(returnOnError) {
* @param {function} reject
* @param {bool} returnOnError
*/
BackendApi.prototype._handleResponse = function(response, resolve, reject, returnOnError) {
logger('Response data:', response.data);
if (!returnOnError && typeof response.data === 'object' && typeof response.data.error === 'object') {
if (typeof response.data === 'object' && typeof response.data.error === 'object' && typeof response.data.error.message !== 'undefined') {
reject(new Error(response.data.error.code + ': ' + response.data.error.message));
BackendApi.prototype._handleResponse = (
response,
resolve,
reject,
returnOnError,
) => {
logger("Response data:", response.data);
if (
!returnOnError &&
typeof response.data === "object" &&
typeof response.data.error === "object"
) {
if (
typeof response.data === "object" &&
typeof response.data.error === "object" &&
typeof response.data.error.message !== "undefined"
) {
reject(
new Error(
`${response.data.error.code}: ${response.data.error.message}`,
),
);
} else {
reject(new Error('Error ' + response.status));
reject(new Error(`Error ${response.status}`));
}
} else {
resolve(response.data);
@@ -63,10 +78,10 @@ BackendApi.prototype._handleResponse = function(response, resolve, reject, retur
* @param {function} reject
* @param {bool} returnOnError
*/
BackendApi.prototype._handleError = function(err, resolve, reject, returnOnError) {
logger('Axios Error:', err);
BackendApi.prototype._handleError = (err, resolve, reject, returnOnError) => {
logger("Axios Error:", err);
if (returnOnError) {
resolve(typeof err.response.data !== 'undefined' ? err.response.data : err);
resolve(typeof err.response.data !== "undefined" ? err.response.data : err);
} else {
reject(err);
}
@@ -84,11 +99,11 @@ BackendApi.prototype.request = function (method, path, returnOnError, data) {
const options = this._prepareOptions(returnOnError);
return new Promise((resolve, reject) => {
let opts = {
const opts = {
method: method,
url: path,
...options
}
...options,
};
if (data !== undefined && data !== null) {
opts.data = data;
}
@@ -110,16 +125,17 @@ BackendApi.prototype.request = function (method, path, returnOnError, data) {
* @returns {Promise<object>}
*/
BackendApi.prototype.postForm = function (path, form, returnOnError) {
logger('POST', this.config.baseUrl + path);
logger("POST", this.config.baseUrl + path);
const options = this._prepareOptions(returnOnError);
return new Promise((resolve, reject) => {
const opts = {
...options,
...form.getHeaders(),
}
};
this.axios.post(path, form, opts)
this.axios
.post(path, form, opts)
.then((response) => {
this._handleResponse(response, resolve, reject, returnOnError);
})
@@ -129,4 +145,4 @@ BackendApi.prototype.postForm = function (path, form, returnOnError) {
});
};
module.exports = BackendApi;
export default BackendApi;

View File

@@ -1,7 +0,0 @@
const _ = require("lodash");
module.exports = function() {
let arr = _.values(arguments);
arr.unshift('[Backend API]');
console.log.apply(null, arr);
};

View File

@@ -0,0 +1,7 @@
const log = (...args) => {
const arr = args;
arr.unshift("[Backend API]");
console.log(...arr);
};
export default log;

View File

@@ -1,13 +1,12 @@
const fs = require('fs');
const FormData = require('form-data');
const logger = require('./logger');
const Client = require('./client');
import fs from "node:fs";
import FormData from "form-data";
import Client from "./client.mjs";
import logger from "./logger.mjs";
module.exports = function (config) {
logger('Client Ready using', config.baseUrl);
export default (config) => {
logger("Client Ready using", config.baseUrl);
return {
/**
* @param {object} options
* @param {string} options.path API path
@@ -18,7 +17,7 @@ module.exports = function (config) {
backendApiGet: (options) => {
const api = new Client(config);
api.setToken(options.token);
return api.request('get', options.path, options.returnOnError || false);
return api.request("get", options.path, options.returnOnError || false);
},
/**
@@ -32,7 +31,12 @@ module.exports = function (config) {
backendApiPost: (options) => {
const api = new Client(config);
api.setToken(options.token);
return api.request('post', options.path, options.returnOnError || false, options.data);
return api.request(
"post",
options.path,
options.returnOnError || false,
options.data,
);
},
/**
@@ -48,8 +52,11 @@ module.exports = function (config) {
api.setToken(options.token);
const form = new FormData();
for (let [key, value] of Object.entries(options.files)) {
form.append(key, fs.createReadStream(config.fixturesFolder + '/' + value));
for (const [key, value] of Object.entries(options.files)) {
form.append(
key,
fs.createReadStream(`${config.fixturesFolder}/${value}`),
);
}
return api.postForm(options.path, form, options.returnOnError || false);
},
@@ -65,7 +72,12 @@ module.exports = function (config) {
backendApiPut: (options) => {
const api = new Client(config);
api.setToken(options.token);
return api.request('put', options.path, options.returnOnError || false, options.data);
return api.request(
"put",
options.path,
options.returnOnError || false,
options.data,
);
},
/**
@@ -78,7 +90,11 @@ module.exports = function (config) {
backendApiDelete: (options) => {
const api = new Client(config);
api.setToken(options.token);
return api.request('delete', options.path, options.returnOnError || false);
}
return api.request(
"delete",
options.path,
options.returnOnError || false,
);
},
};
};

View File

@@ -1,20 +1,26 @@
import { SwaggerValidation } from '@jc21/cypress-swagger-validation';
import chalk from 'chalk';
import { SwaggerValidation } from "@jc21/cypress-swagger-validation";
import chalk from "chalk";
import backendTask from "./backendApi/task.mjs";
export default (on, config) => {
// Replace swaggerBase config var wildcard
if (typeof config.env.swaggerBase !== 'undefined') {
config.env.swaggerBase = config.env.swaggerBase.replace('{{baseUrl}}', config.baseUrl);
if (typeof config.env.swaggerBase !== "undefined") {
config.env.swaggerBase = config.env.swaggerBase.replace(
"{{baseUrl}}",
config.baseUrl,
);
}
// Plugin Events
on('task', SwaggerValidation(config));
on('task', require('./backendApi/task')(config));
on('task', {
on("task", SwaggerValidation(config));
on("task", backendTask(config));
on("task", {
log(message) {
console.log(`${chalk.cyan.bold('[')}${chalk.blue.bold('LOG')}${chalk.cyan.bold(']')} ${chalk.red.bold(message)}`);
console.log(
`${chalk.cyan.bold("[")}${chalk.blue.bold("LOG")}${chalk.cyan.bold("]")} ${chalk.red.bold(message)}`,
);
return null;
}
},
});
return config;

View File

@@ -35,7 +35,7 @@ Cypress.Commands.add("validateSwaggerFile", (url, savePath) => {
.then((response) => cy.writeFile(savePath, response.body, { log: false }))
.then(() => cy.exec(`yarn swagger-lint '${savePath}'`, { failOnNonZeroExit: false }))
.then((result) => cy.task('log', `Swagger Vacuum Results:\n${result.stdout || ''}`)
.then(() => expect(result.code).to.eq(0)));
.then(() => expect(result.exitCode).to.eq(0)));
});
});

View File

@@ -1,4 +1,4 @@
import './commands';
import './commands.mjs';
Cypress.on('uncaught:exception', (/*err, runnable*/) => {
// returning false here prevents Cypress from

View File

@@ -4,6 +4,10 @@
"cypress/**/*.js",
"cypress/config/dev.mjs",
"cypress/config/ci.mjs",
"cypress/plugins/index.mjs"
"cypress/plugins/index.mjs",
"cypress/plugins/backendApi/task.mjs",
"cypress/plugins/backendApi/logger.mjs",
"cypress/plugins/backendApi/client.mjs",
"cypress/support/commands.mjs"
]
}