Cypress ...

This commit is contained in:
Jamie Curnow
2026-01-27 11:22:16 +10:00
parent 28982b8bc2
commit 9b7af474bb
8 changed files with 103 additions and 61 deletions

View File

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

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 @@
import _ from "lodash";
export default () => {
const arr = _.values(arguments);
arr.unshift('[Backend API]');
console.log.apply(null, arr);
};

View File

@@ -1,13 +1,12 @@
const fs = require('fs'); import fs from "node:fs";
const FormData = require('form-data'); import FormData from "form-data";
const logger = require('./logger'); import Client from "./client.mjs";
const Client = require('./client'); import logger from "./logger.mjs";
module.exports = function (config) { export default (config) => {
logger('Client Ready using', config.baseUrl); logger("Client Ready using", config.baseUrl);
return { return {
/** /**
* @param {object} options * @param {object} options
* @param {string} options.path API path * @param {string} options.path API path
@@ -18,7 +17,7 @@ module.exports = function (config) {
backendApiGet: (options) => { backendApiGet: (options) => {
const api = new Client(config); const api = new Client(config);
api.setToken(options.token); 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) => { backendApiPost: (options) => {
const api = new Client(config); const api = new Client(config);
api.setToken(options.token); 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); api.setToken(options.token);
const form = new FormData(); const form = new FormData();
for (let [key, value] of Object.entries(options.files)) { for (const [key, value] of Object.entries(options.files)) {
form.append(key, fs.createReadStream(config.fixturesFolder + '/' + value)); form.append(
key,
fs.createReadStream(`${config.fixturesFolder}/${value}`),
);
} }
return api.postForm(options.path, form, options.returnOnError || false); return api.postForm(options.path, form, options.returnOnError || false);
}, },
@@ -65,7 +72,12 @@ module.exports = function (config) {
backendApiPut: (options) => { backendApiPut: (options) => {
const api = new Client(config); const api = new Client(config);
api.setToken(options.token); 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) => { backendApiDelete: (options) => {
const api = new Client(config); const api = new Client(config);
api.setToken(options.token); 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 { SwaggerValidation } from "@jc21/cypress-swagger-validation";
import chalk from 'chalk'; import chalk from "chalk";
import backendTask from "./backendApi/task.mjs";
export default (on, config) => { export default (on, config) => {
// Replace swaggerBase config var wildcard // Replace swaggerBase config var wildcard
if (typeof config.env.swaggerBase !== 'undefined') { if (typeof config.env.swaggerBase !== "undefined") {
config.env.swaggerBase = config.env.swaggerBase.replace('{{baseUrl}}', config.baseUrl); config.env.swaggerBase = config.env.swaggerBase.replace(
"{{baseUrl}}",
config.baseUrl,
);
} }
// Plugin Events // Plugin Events
on('task', SwaggerValidation(config)); on("task", SwaggerValidation(config));
on('task', require('./backendApi/task')(config)); on("task", backendTask(config));
on('task', { on("task", {
log(message) { 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 null;
} },
}); });
return config; return config;

View File

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

View File

@@ -4,6 +4,10 @@
"cypress/**/*.js", "cypress/**/*.js",
"cypress/config/dev.mjs", "cypress/config/dev.mjs",
"cypress/config/ci.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"
] ]
} }