From 12ee632923d5b59ff1d010b90f57fbd123a64cbc Mon Sep 17 00:00:00 2001 From: Mali Oz Date: Wed, 27 Mar 2024 19:17:26 -0300 Subject: [PATCH 01/13] cypress hello world --- cypress.config.js | 19 + docker-compose.yml | 7 + tests/cypress/integration/example.cy.js | 7 + tests/cypress/plugins/index.js | 23 + tests/cypress/plugins/swap-env.js | 21 + tests/cypress/support/assertions.js | 3 + tests/cypress/support/index.d.ts | 92 ++++ tests/cypress/support/index.js | 32 ++ tests/cypress/support/laravel-commands.js | 301 +++++++++++ tests/cypress/support/laravel-routes.js | 21 + tests/cypress/support/routes.json | 625 ++++++++++++++++++++++ 11 files changed, 1151 insertions(+) create mode 100644 cypress.config.js create mode 100644 tests/cypress/integration/example.cy.js create mode 100644 tests/cypress/plugins/index.js create mode 100644 tests/cypress/plugins/swap-env.js create mode 100644 tests/cypress/support/assertions.js create mode 100644 tests/cypress/support/index.d.ts create mode 100644 tests/cypress/support/index.js create mode 100644 tests/cypress/support/laravel-commands.js create mode 100644 tests/cypress/support/laravel-routes.js create mode 100644 tests/cypress/support/routes.json diff --git a/cypress.config.js b/cypress.config.js new file mode 100644 index 0000000..6100f0f --- /dev/null +++ b/cypress.config.js @@ -0,0 +1,19 @@ +const { defineConfig } = require('cypress') + +module.exports = defineConfig({ + chromeWebSecurity: false, + retries: 2, + defaultCommandTimeout: 5000, + watchForFileChanges: false, + videosFolder: 'tests/cypress/videos', + screenshotsFolder: 'tests/cypress/screenshots', + fixturesFolder: 'tests/cypress/fixture', + e2e: { + setupNodeEvents(on, config) { + return require('./tests/cypress/plugins/index.js')(on, config) + }, + baseUrl: 'http://app', + specPattern: 'tests/cypress/integration/**/*.cy.{js,jsx,ts,tsx}', + supportFile: 'tests/cypress/support/index.js', + }, +}) diff --git a/docker-compose.yml b/docker-compose.yml index 82a5822..c883091 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -46,6 +46,13 @@ services: volumes: - './storage/app/public/arquivos:/arquivos' - './storage/app/temp:/temp' + cypress: + image: 'cypress/included' + volumes: + - '.:/var/www/html' + working_dir: '/var/www/html' + networks: + - sail networks: sail: driver: bridge diff --git a/tests/cypress/integration/example.cy.js b/tests/cypress/integration/example.cy.js new file mode 100644 index 0000000..b93866c --- /dev/null +++ b/tests/cypress/integration/example.cy.js @@ -0,0 +1,7 @@ +describe('Example Test', () => { + it('shows a homepage', () => { + cy.visit('/'); + + cy.contains('notaR'); + }); +}); diff --git a/tests/cypress/plugins/index.js b/tests/cypress/plugins/index.js new file mode 100644 index 0000000..0c78445 --- /dev/null +++ b/tests/cypress/plugins/index.js @@ -0,0 +1,23 @@ +/// +// *********************************************************** +// This example plugins/index.js can be used to load plugins +// +// You can change the location of this file or turn off loading +// the plugins file with the 'pluginsFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/plugins-guide +// *********************************************************** + +// This function is called when a project is opened or re-opened (e.g. due to +// the project's config changing) + +/** + * @type {Cypress.PluginConfig} + */ +module.exports = (on, config) => { + // `on` is used to hook into various events Cypress emits + // `config` is the resolved Cypress config + + on('task', require('./swap-env')); +}; diff --git a/tests/cypress/plugins/swap-env.js b/tests/cypress/plugins/swap-env.js new file mode 100644 index 0000000..aee03e7 --- /dev/null +++ b/tests/cypress/plugins/swap-env.js @@ -0,0 +1,21 @@ +let fs = require('fs'); + +module.exports = { + activateCypressEnvFile() { + if (fs.existsSync('.env.cypress')) { + fs.renameSync('.env', '.env.backup'); + fs.renameSync('.env.cypress', '.env'); + } + + return null; + }, + + activateLocalEnvFile() { + if (fs.existsSync('.env.backup')) { + fs.renameSync('.env', '.env.cypress'); + fs.renameSync('.env.backup', '.env'); + } + + return null; + } +}; diff --git a/tests/cypress/support/assertions.js b/tests/cypress/support/assertions.js new file mode 100644 index 0000000..5f0855a --- /dev/null +++ b/tests/cypress/support/assertions.js @@ -0,0 +1,3 @@ +Cypress.Commands.add('assertRedirect', path => { + cy.location('pathname').should('eq', `/${path}`.replace(/^\/\//, '/')); +}); diff --git a/tests/cypress/support/index.d.ts b/tests/cypress/support/index.d.ts new file mode 100644 index 0000000..eb52d46 --- /dev/null +++ b/tests/cypress/support/index.d.ts @@ -0,0 +1,92 @@ +/// + +declare namespace Cypress { + interface Chainable { + /** + * Log in the user with the given attributes, or create a new user and then log them in. + * + * @example + * cy.login() + * cy.login({ id: 1 }) + */ + login(attributes?: object): Chainable; + + /** + * Log out the current user. + * + * @example + * cy.logout() + */ + logout(): Chainable; + + /** + * Fetch the currently authenticated user. + * + * @example + * cy.currentUser() + */ + currentUser(): Chainable; + + /** + * Fetch a CSRF token from the server. + * + * @example + * cy.logout() + */ + csrfToken(): Chainable; + + /** + * Fetch a fresh list of URI routes from the server. + * + * @example + * cy.logout() + */ + refreshRoutes(): Chainable; + + /** + * Create and persist a new Eloquent record using Laravel model factories. + * + * @example + * cy.create('App\\User'); + * cy.create('App\\User', 2); + * cy.create('App\\User', 2, { active: false }); + * cy.create({ model: 'App\\User', state: ['guest'], relations: ['profile'], count: 2 } + */ + create(): Chainable; + + /** + * Refresh the database state using Laravel's migrate:fresh command. + * + * @example + * cy.refreshDatabase() + * cy.refreshDatabase({ '--drop-views': true } + */ + refreshDatabase(options?: object): Chainable; + + /** + * Run Artisan's db:seed command. + * + * @example + * cy.seed() + * cy.seed('PlansTableSeeder') + */ + seed(seederClass?: string): Chainable; + + /** + * Run an Artisan command. + * + * @example + * cy.artisan() + */ + artisan(command: string, parameters?: object, options?: object): Chainable; + + /** + * Execute arbitrary PHP on the server. + * + * @example + * cy.php('2 + 2') + * cy.php('App\\User::count()') + */ + php(command: string): Chainable; + } +} diff --git a/tests/cypress/support/index.js b/tests/cypress/support/index.js new file mode 100644 index 0000000..e3b5c4c --- /dev/null +++ b/tests/cypress/support/index.js @@ -0,0 +1,32 @@ +// *********************************************************** +// This example support/index.js is processed and +// loaded automatically before your test files. +// +// This is a great place to put global configuration and +// behavior that modifies Cypress. +// +// You can change the location of this file or turn off +// automatically serving support files with the +// 'supportFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/configuration +// *********************************************************** + +/// + +import './laravel-commands'; +import './laravel-routes'; +import './assertions'; + +before(() => { + cy.task('activateCypressEnvFile', {}, { log: false }); + cy.artisan('config:clear', {}, { log: false }); + + cy.refreshRoutes(); +}); + +after(() => { + cy.task('activateLocalEnvFile', {}, { log: false }); + cy.artisan('config:clear', {}, { log: false }); +}); diff --git a/tests/cypress/support/laravel-commands.js b/tests/cypress/support/laravel-commands.js new file mode 100644 index 0000000..9af6c64 --- /dev/null +++ b/tests/cypress/support/laravel-commands.js @@ -0,0 +1,301 @@ +/** + * Create a new user and log them in. + * + * @param {Object} attributes + * + * @example cy.login(); + * cy.login({ name: 'JohnDoe' }); + * cy.login({ attributes: { name: 'JohnDoe' }, state: 'guest', load: ['comments] }); + */ +Cypress.Commands.add('login', (attributes = {}) => { + // Are we using the new object system. + let requestBody = attributes.attributes || attributes.state || attributes.load ? attributes : { attributes }; + + return cy + .csrfToken() + .then((token) => { + return cy.request({ + method: 'POST', + url: '/__cypress__/login', + body: { ...requestBody, _token: token }, + log: false, + }); + }) + .then(({ body }) => { + Cypress.Laravel.currentUser = body; + + Cypress.log({ + name: 'login', + message: JSON.stringify(body), + consoleProps: () => ({ user: body }), + }); + }) + .its('body', { log: false }); +}); + +/** + * Fetch the currently authenticated user object. + * + * @example cy.currentUser(); + */ +Cypress.Commands.add('currentUser', () => { + return cy.csrfToken().then((token) => { + return cy + .request({ + method: 'POST', + url: '/__cypress__/current-user', + body: { _token: token }, + log: false, + }) + .then((response) => { + if (!response.body) { + cy.log('No authenticated user found.'); + } + + Cypress.Laravel.currentUser = response?.body; + + return response?.body; + }); + }); +}); + + +/** + * Logout the current user. + * + * @example cy.logout(); + */ +Cypress.Commands.add('logout', () => { + return cy + .csrfToken() + .then((token) => { + return cy.request({ + method: 'POST', + url: '/__cypress__/logout', + body: { _token: token }, + log: false, + }); + }) + .then(() => { + Cypress.log({ name: 'logout', message: '' }); + }); +}); + +/** + * Fetch a CSRF token. + * + * @example cy.csrfToken(); + */ +Cypress.Commands.add('csrfToken', () => { + return cy + .request({ + method: 'GET', + url: '/__cypress__/csrf_token', + log: false, + }) + .its('body', { log: false }); +}); + +/** + * Fetch and store all named routes. + * + * @example cy.refreshRoutes(); + */ +Cypress.Commands.add('refreshRoutes', () => { + return cy.csrfToken().then((token) => { + return cy + .request({ + method: 'POST', + url: '/__cypress__/routes', + body: { _token: token }, + log: false, + }) + .its('body', { log: false }) + .then((routes) => { + cy.writeFile(Cypress.config().supportFolder + '/routes.json', routes, { + log: false, + }); + + Cypress.Laravel.routes = routes; + }); + }); +}); + +/** + * Visit the given URL or route. + * + * @example cy.visit('foo/path'); + * cy.visit({ route: 'home' }); + * cy.visit({ route: 'team', parameters: { team: 1 } }); + */ +Cypress.Commands.overwrite('visit', (originalFn, subject, options) => { + if (subject.route) { + return originalFn({ + url: Cypress.Laravel.route(subject.route, subject.parameters || {}), + method: Cypress.Laravel.routes[subject.route].method[0], + ...options + }); + } + + return originalFn(subject, options); +}); + +/** + * Create a new Eloquent factory. + * + * @param {String} model + * @param {Number|null} times + * @param {Object} attributes + * + * @example cy.create('App\\User'); + * cy.create('App\\User', 2); + * cy.create('App\\User', 2, { active: false }); + * cy.create('App\\User', { active: false }); + * cy.create('App\\User', 2, { active: false }); + * cy.create('App\\User', 2, { active: false }, ['profile']); + * cy.create('App\\User', 2, { active: false }, ['profile'], ['guest']); + * cy.create('App\\User', { active: false }, ['profile']); + * cy.create('App\\User', { active: false }, ['profile'], ['guest']); + * cy.create('App\\User', ['profile']); + * cy.create('App\\User', ['profile'], ['guest']); + * cy.create({ model: 'App\\User', state: ['guest'], relations: ['profile'], count: 2 } + */ +Cypress.Commands.add('create', (model, count = 1, attributes = {}, load = [], state = []) => { + let requestBody = {}; + + if (typeof model !== 'object') { + if (Array.isArray(count)) { + state = attributes; + attributes = {}; + load = count; + count = 1; + } + + if (typeof count === 'object') { + state = load; + load = attributes; + attributes = count; + count = 1; + } + + requestBody = { model, state, attributes, load, count }; + } else { + requestBody = model; + } + + return cy + .csrfToken() + .then((token) => { + return cy.request({ + method: 'POST', + url: '/__cypress__/factory', + body: { ...requestBody, _token: token }, + log: false, + }); + }) + .then((response) => { + Cypress.log({ + name: 'create', + message: requestBody.model + (requestBody.count > 1 ? ` (${requestBody.count} times)` : ''), + consoleProps: () => ({ [model]: response.body }), + }); + }) + .its('body', { log: false }); +}); + +/** + * Refresh the database state. + * + * @param {Object} options + * + * @example cy.refreshDatabase(); + * cy.refreshDatabase({ '--drop-views': true }); + */ +Cypress.Commands.add('refreshDatabase', (options = {}) => { + return cy.artisan('migrate:fresh', options); +}); + +/** + * Seed the database. + * + * @param {String} seederClass + * + * @example cy.seed(); + * cy.seed('PlansTableSeeder'); + */ +Cypress.Commands.add('seed', (seederClass = '') => { + let options = {}; + + if (seederClass) { + options['--class'] = seederClass; + } + + return cy.artisan('db:seed', options); +}); + +/** + * Trigger an Artisan command. + * + * @param {String} command + * @param {Object} parameters + * @param {Object} options + * + * @example cy.artisan('cache:clear'); + */ +Cypress.Commands.add('artisan', (command, parameters = {}, options = {}) => { + options = Object.assign({}, { log: true }, options); + + if (options.log) { + Cypress.log({ + name: 'artisan', + message: (() => { + let message = command; + + for (let key in parameters) { + message += ` ${key}="${parameters[key]}"`; + } + + return message; + })(), + consoleProps: () => ({ command, parameters }), + }); + } + + return cy.csrfToken().then((token) => { + return cy.request({ + method: 'POST', + url: '/__cypress__/artisan', + body: { command: command, parameters: parameters, _token: token }, + log: false, + }); + }); +}); + +/** + * Execute arbitrary PHP. + * + * @param {String} command + * + * @example cy.php('2 + 2'); + * cy.php('App\\User::count()'); + */ +Cypress.Commands.add('php', (command) => { + return cy + .csrfToken() + .then((token) => { + return cy.request({ + method: 'POST', + url: '/__cypress__/run-php', + body: { command: command, _token: token }, + log: false, + }); + }) + .then((response) => { + Cypress.log({ + name: 'php', + message: command, + consoleProps: () => ({ result: response.body.result }), + }); + }) + .its('body.result', { log: false }); +}); diff --git a/tests/cypress/support/laravel-routes.js b/tests/cypress/support/laravel-routes.js new file mode 100644 index 0000000..a87966a --- /dev/null +++ b/tests/cypress/support/laravel-routes.js @@ -0,0 +1,21 @@ +Cypress.Laravel = { + routes: {}, + + route: (name, parameters = {}) => { + assert( + Cypress.Laravel.routes.hasOwnProperty(name), + `Laravel route "${name}" does not exist.` + ); + + return ((uri) => { + Object.keys(parameters).forEach((parameter) => { + uri = uri.replace( + new RegExp(`{${parameter}}`), + parameters[parameter] + ); + }); + + return uri; + })(Cypress.Laravel.routes[name].uri); + }, +}; diff --git a/tests/cypress/support/routes.json b/tests/cypress/support/routes.json new file mode 100644 index 0000000..dd175f7 --- /dev/null +++ b/tests/cypress/support/routes.json @@ -0,0 +1,625 @@ +{ + "debugbar.openhandler": { + "name": "debugbar.openhandler", + "domain": null, + "action": "Barryvdh\\Debugbar\\Controllers\\OpenHandlerController@handle", + "uri": "_debugbar/open", + "method": [ + "GET", + "HEAD" + ] + }, + "debugbar.clockwork": { + "name": "debugbar.clockwork", + "domain": null, + "action": "Barryvdh\\Debugbar\\Controllers\\OpenHandlerController@clockwork", + "uri": "_debugbar/clockwork/{id}", + "method": [ + "GET", + "HEAD" + ] + }, + "debugbar.assets.css": { + "name": "debugbar.assets.css", + "domain": null, + "action": "Barryvdh\\Debugbar\\Controllers\\AssetController@css", + "uri": "_debugbar/assets/stylesheets", + "method": [ + "GET", + "HEAD" + ] + }, + "debugbar.assets.js": { + "name": "debugbar.assets.js", + "domain": null, + "action": "Barryvdh\\Debugbar\\Controllers\\AssetController@js", + "uri": "_debugbar/assets/javascript", + "method": [ + "GET", + "HEAD" + ] + }, + "debugbar.cache.delete": { + "name": "debugbar.cache.delete", + "domain": null, + "action": "Barryvdh\\Debugbar\\Controllers\\CacheController@delete", + "uri": "_debugbar/cache/{key}/{tags?}", + "method": [ + "DELETE" + ] + }, + "cypress.factory": { + "name": "cypress.factory", + "domain": null, + "action": "Laracasts\\Cypress\\Controllers\\CypressController@factory", + "uri": "__cypress__/factory", + "method": [ + "POST" + ] + }, + "cypress.login": { + "name": "cypress.login", + "domain": null, + "action": "Laracasts\\Cypress\\Controllers\\CypressController@login", + "uri": "__cypress__/login", + "method": [ + "POST" + ] + }, + "cypress.logout": { + "name": "cypress.logout", + "domain": null, + "action": "Laracasts\\Cypress\\Controllers\\CypressController@logout", + "uri": "__cypress__/logout", + "method": [ + "POST" + ] + }, + "cypress.artisan": { + "name": "cypress.artisan", + "domain": null, + "action": "Laracasts\\Cypress\\Controllers\\CypressController@artisan", + "uri": "__cypress__/artisan", + "method": [ + "POST" + ] + }, + "cypress.run-php": { + "name": "cypress.run-php", + "domain": null, + "action": "Laracasts\\Cypress\\Controllers\\CypressController@runPhp", + "uri": "__cypress__/run-php", + "method": [ + "POST" + ] + }, + "cypress.csrf-token": { + "name": "cypress.csrf-token", + "domain": null, + "action": "Laracasts\\Cypress\\Controllers\\CypressController@csrfToken", + "uri": "__cypress__/csrf_token", + "method": [ + "GET", + "HEAD" + ] + }, + "cypress.routes": { + "name": "cypress.routes", + "domain": null, + "action": "Laracasts\\Cypress\\Controllers\\CypressController@routes", + "uri": "__cypress__/routes", + "method": [ + "POST" + ] + }, + "cypress.current-user": { + "name": "cypress.current-user", + "domain": null, + "action": "Laracasts\\Cypress\\Controllers\\CypressController@currentUser", + "uri": "__cypress__/current-user", + "method": [ + "POST" + ] + }, + "ignition.healthCheck": { + "name": "ignition.healthCheck", + "domain": null, + "action": "Spatie\\LaravelIgnition\\Http\\Controllers\\HealthCheckController", + "uri": "_ignition/health-check", + "method": [ + "GET", + "HEAD" + ] + }, + "ignition.executeSolution": { + "name": "ignition.executeSolution", + "domain": null, + "action": "Spatie\\LaravelIgnition\\Http\\Controllers\\ExecuteSolutionController", + "uri": "_ignition/execute-solution", + "method": [ + "POST" + ] + }, + "ignition.updateConfig": { + "name": "ignition.updateConfig", + "domain": null, + "action": "Spatie\\LaravelIgnition\\Http\\Controllers\\UpdateConfigController", + "uri": "_ignition/update-config", + "method": [ + "POST" + ] + }, + "": { + "name": null, + "domain": null, + "action": "App\\Http\\Controllers\\Auth\\AuthenticatedSessionController@store", + "uri": "login", + "method": [ + "POST" + ] + }, + "exercicio.import": { + "name": "exercicio.import", + "domain": null, + "action": "App\\Http\\Controllers\\ExercicioController@import", + "uri": "exercicio/import", + "method": [ + "PUT" + ] + }, + "exercicio.submit": { + "name": "exercicio.submit", + "domain": null, + "action": "App\\Http\\Controllers\\ExercicioController@submit", + "uri": "exercicio/{exercicio}", + "method": [ + "POST" + ] + }, + "exercicio.upload": { + "name": "exercicio.upload", + "domain": null, + "action": "App\\Http\\Controllers\\ExercicioController@upload", + "uri": "exercicio/{exercicio}/upload", + "method": [ + "POST" + ] + }, + "exercicio.export": { + "name": "exercicio.export", + "domain": null, + "action": "App\\Http\\Controllers\\ExercicioController@export", + "uri": "exercicio/{exercicio}/export", + "method": [ + "GET", + "HEAD" + ] + }, + "user.index": { + "name": "user.index", + "domain": null, + "action": "App\\Http\\Controllers\\UserController@index", + "uri": "user", + "method": [ + "GET", + "HEAD" + ] + }, + "user.create": { + "name": "user.create", + "domain": null, + "action": "App\\Http\\Controllers\\UserController@create", + "uri": "user/create", + "method": [ + "GET", + "HEAD" + ] + }, + "user.store": { + "name": "user.store", + "domain": null, + "action": "App\\Http\\Controllers\\UserController@store", + "uri": "user", + "method": [ + "POST" + ] + }, + "user.show": { + "name": "user.show", + "domain": null, + "action": "App\\Http\\Controllers\\UserController@show", + "uri": "user/{user}", + "method": [ + "GET", + "HEAD" + ] + }, + "user.edit": { + "name": "user.edit", + "domain": null, + "action": "App\\Http\\Controllers\\UserController@edit", + "uri": "user/{user}/edit", + "method": [ + "GET", + "HEAD" + ] + }, + "user.update": { + "name": "user.update", + "domain": null, + "action": "App\\Http\\Controllers\\UserController@update", + "uri": "user/{user}", + "method": [ + "PUT", + "PATCH" + ] + }, + "user.destroy": { + "name": "user.destroy", + "domain": null, + "action": "App\\Http\\Controllers\\UserController@destroy", + "uri": "user/{user}", + "method": [ + "DELETE" + ] + }, + "turma.index": { + "name": "turma.index", + "domain": null, + "action": "App\\Http\\Controllers\\TurmaController@index", + "uri": "turma", + "method": [ + "GET", + "HEAD" + ] + }, + "turma.create": { + "name": "turma.create", + "domain": null, + "action": "App\\Http\\Controllers\\TurmaController@create", + "uri": "turma/create", + "method": [ + "GET", + "HEAD" + ] + }, + "turma.store": { + "name": "turma.store", + "domain": null, + "action": "App\\Http\\Controllers\\TurmaController@store", + "uri": "turma", + "method": [ + "POST" + ] + }, + "turma.show": { + "name": "turma.show", + "domain": null, + "action": "App\\Http\\Controllers\\TurmaController@show", + "uri": "turma/{turma}", + "method": [ + "GET", + "HEAD" + ] + }, + "turma.edit": { + "name": "turma.edit", + "domain": null, + "action": "App\\Http\\Controllers\\TurmaController@edit", + "uri": "turma/{turma}/edit", + "method": [ + "GET", + "HEAD" + ] + }, + "turma.update": { + "name": "turma.update", + "domain": null, + "action": "App\\Http\\Controllers\\TurmaController@update", + "uri": "turma/{turma}", + "method": [ + "PUT", + "PATCH" + ] + }, + "turma.destroy": { + "name": "turma.destroy", + "domain": null, + "action": "App\\Http\\Controllers\\TurmaController@destroy", + "uri": "turma/{turma}", + "method": [ + "DELETE" + ] + }, + "exercicio.index": { + "name": "exercicio.index", + "domain": null, + "action": "App\\Http\\Controllers\\ExercicioController@index", + "uri": "exercicio", + "method": [ + "GET", + "HEAD" + ] + }, + "exercicio.create": { + "name": "exercicio.create", + "domain": null, + "action": "App\\Http\\Controllers\\ExercicioController@create", + "uri": "exercicio/create", + "method": [ + "GET", + "HEAD" + ] + }, + "exercicio.store": { + "name": "exercicio.store", + "domain": null, + "action": "App\\Http\\Controllers\\ExercicioController@store", + "uri": "exercicio", + "method": [ + "POST" + ] + }, + "exercicio.show": { + "name": "exercicio.show", + "domain": null, + "action": "App\\Http\\Controllers\\ExercicioController@show", + "uri": "exercicio/{exercicio}", + "method": [ + "GET", + "HEAD" + ] + }, + "exercicio.edit": { + "name": "exercicio.edit", + "domain": null, + "action": "App\\Http\\Controllers\\ExercicioController@edit", + "uri": "exercicio/{exercicio}/edit", + "method": [ + "GET", + "HEAD" + ] + }, + "exercicio.update": { + "name": "exercicio.update", + "domain": null, + "action": "App\\Http\\Controllers\\ExercicioController@update", + "uri": "exercicio/{exercicio}", + "method": [ + "PUT", + "PATCH" + ] + }, + "exercicio.destroy": { + "name": "exercicio.destroy", + "domain": null, + "action": "App\\Http\\Controllers\\ExercicioController@destroy", + "uri": "exercicio/{exercicio}", + "method": [ + "DELETE" + ] + }, + "prazo.index": { + "name": "prazo.index", + "domain": null, + "action": "App\\Http\\Controllers\\PrazoController@index", + "uri": "prazo", + "method": [ + "GET", + "HEAD" + ] + }, + "prazo.create": { + "name": "prazo.create", + "domain": null, + "action": "App\\Http\\Controllers\\PrazoController@create", + "uri": "prazo/create", + "method": [ + "GET", + "HEAD" + ] + }, + "prazo.store": { + "name": "prazo.store", + "domain": null, + "action": "App\\Http\\Controllers\\PrazoController@store", + "uri": "prazo", + "method": [ + "POST" + ] + }, + "prazo.show": { + "name": "prazo.show", + "domain": null, + "action": "App\\Http\\Controllers\\PrazoController@show", + "uri": "prazo/{prazo}", + "method": [ + "GET", + "HEAD" + ] + }, + "prazo.edit": { + "name": "prazo.edit", + "domain": null, + "action": "App\\Http\\Controllers\\PrazoController@edit", + "uri": "prazo/{prazo}/edit", + "method": [ + "GET", + "HEAD" + ] + }, + "prazo.update": { + "name": "prazo.update", + "domain": null, + "action": "App\\Http\\Controllers\\PrazoController@update", + "uri": "prazo/{prazo}", + "method": [ + "PUT", + "PATCH" + ] + }, + "prazo.destroy": { + "name": "prazo.destroy", + "domain": null, + "action": "App\\Http\\Controllers\\PrazoController@destroy", + "uri": "prazo/{prazo}", + "method": [ + "DELETE" + ] + }, + "arquivo.index": { + "name": "arquivo.index", + "domain": null, + "action": "App\\Http\\Controllers\\ArquivoController@index", + "uri": "arquivo", + "method": [ + "GET", + "HEAD" + ] + }, + "arquivo.create": { + "name": "arquivo.create", + "domain": null, + "action": "App\\Http\\Controllers\\ArquivoController@create", + "uri": "arquivo/create", + "method": [ + "GET", + "HEAD" + ] + }, + "arquivo.store": { + "name": "arquivo.store", + "domain": null, + "action": "App\\Http\\Controllers\\ArquivoController@store", + "uri": "arquivo", + "method": [ + "POST" + ] + }, + "arquivo.show": { + "name": "arquivo.show", + "domain": null, + "action": "App\\Http\\Controllers\\ArquivoController@show", + "uri": "arquivo/{arquivo}", + "method": [ + "GET", + "HEAD" + ] + }, + "arquivo.edit": { + "name": "arquivo.edit", + "domain": null, + "action": "App\\Http\\Controllers\\ArquivoController@edit", + "uri": "arquivo/{arquivo}/edit", + "method": [ + "GET", + "HEAD" + ] + }, + "arquivo.update": { + "name": "arquivo.update", + "domain": null, + "action": "App\\Http\\Controllers\\ArquivoController@update", + "uri": "arquivo/{arquivo}", + "method": [ + "PUT", + "PATCH" + ] + }, + "arquivo.destroy": { + "name": "arquivo.destroy", + "domain": null, + "action": "App\\Http\\Controllers\\ArquivoController@destroy", + "uri": "arquivo/{arquivo}", + "method": [ + "DELETE" + ] + }, + "impedimento.index": { + "name": "impedimento.index", + "domain": null, + "action": "App\\Http\\Controllers\\ImpedimentoController@index", + "uri": "impedimento", + "method": [ + "GET", + "HEAD" + ] + }, + "impedimento.create": { + "name": "impedimento.create", + "domain": null, + "action": "App\\Http\\Controllers\\ImpedimentoController@create", + "uri": "impedimento/create", + "method": [ + "GET", + "HEAD" + ] + }, + "impedimento.store": { + "name": "impedimento.store", + "domain": null, + "action": "App\\Http\\Controllers\\ImpedimentoController@store", + "uri": "impedimento", + "method": [ + "POST" + ] + }, + "impedimento.show": { + "name": "impedimento.show", + "domain": null, + "action": "App\\Http\\Controllers\\ImpedimentoController@show", + "uri": "impedimento/{impedimento}", + "method": [ + "GET", + "HEAD" + ] + }, + "impedimento.edit": { + "name": "impedimento.edit", + "domain": null, + "action": "App\\Http\\Controllers\\ImpedimentoController@edit", + "uri": "impedimento/{impedimento}/edit", + "method": [ + "GET", + "HEAD" + ] + }, + "impedimento.update": { + "name": "impedimento.update", + "domain": null, + "action": "App\\Http\\Controllers\\ImpedimentoController@update", + "uri": "impedimento/{impedimento}", + "method": [ + "PUT", + "PATCH" + ] + }, + "impedimento.destroy": { + "name": "impedimento.destroy", + "domain": null, + "action": "App\\Http\\Controllers\\ImpedimentoController@destroy", + "uri": "impedimento/{impedimento}", + "method": [ + "DELETE" + ] + }, + "login": { + "name": "login", + "domain": null, + "action": "App\\Http\\Controllers\\Auth\\AuthenticatedSessionController@create", + "uri": "login", + "method": [ + "GET", + "HEAD" + ] + }, + "logout": { + "name": "logout", + "domain": null, + "action": "App\\Http\\Controllers\\Auth\\AuthenticatedSessionController@destroy", + "uri": "logout", + "method": [ + "POST" + ] + } +} \ No newline at end of file From fff869f772ae644693d7d0e54873fda4e989cd9d Mon Sep 17 00:00:00 2001 From: Mali Oz Date: Thu, 28 Mar 2024 18:36:42 -0300 Subject: [PATCH 02/13] CYPRESS LOCAL --- cypress.config.js | 2 +- package-lock.json | 1220 ++++++++++++++++++++++- package.json | 1 + tests/cypress/integration/example.cy.js | 10 + 4 files changed, 1225 insertions(+), 8 deletions(-) diff --git a/cypress.config.js b/cypress.config.js index 6100f0f..62d3205 100644 --- a/cypress.config.js +++ b/cypress.config.js @@ -12,7 +12,7 @@ module.exports = defineConfig({ setupNodeEvents(on, config) { return require('./tests/cypress/plugins/index.js')(on, config) }, - baseUrl: 'http://app', + baseUrl: 'http://localhost:8000', specPattern: 'tests/cypress/integration/**/*.cy.{js,jsx,ts,tsx}', supportFile: 'tests/cypress/support/index.js', }, diff --git a/package-lock.json b/package-lock.json index 4405116..f2a4d28 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,14 +1,14 @@ { - "name": "html", + "name": "notaR", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "html", "devDependencies": { "@fortawesome/fontawesome-free": "^5.15.2", "axios": "^1.6.8", "bootstrap": "^4.0.0", + "cypress": "^13.7.1", "font-awesome": "^4.7.0", "jquery": "^3.2", "jquery-ui": "^1.12.1", @@ -1852,6 +1852,83 @@ "node": ">=0.1.90" } }, + "node_modules/@cypress/request": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.1.tgz", + "integrity": "sha512-TWivJlJi8ZDx2wGOw1dbLuHJKUYX7bWySw377nlnGOW3hP9/MUKIsEdXT/YngWxVdgNCHRBmFlBipE+5/2ZZlQ==", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "http-signature": "~1.3.6", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "performance-now": "^2.1.0", + "qs": "6.10.4", + "safe-buffer": "^5.1.2", + "tough-cookie": "^4.1.3", + "tunnel-agent": "^0.6.0", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@cypress/request/node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/@cypress/request/node_modules/qs": { + "version": "6.10.4", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.4.tgz", + "integrity": "sha512-OQiU+C+Ds5qiH91qh/mg0w+8nwQuLjM4F4M/PbmhDOoYehPh+Fb0bDjtR1sOvy7YKxvj28Y/M0PhP5uVX0kB+g==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@cypress/xvfb": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz", + "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==", + "dev": true, + "dependencies": { + "debug": "^3.1.0", + "lodash.once": "^4.1.1" + } + }, + "node_modules/@cypress/xvfb/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", @@ -2279,6 +2356,18 @@ "@types/node": "*" } }, + "node_modules/@types/sinonjs__fake-timers": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz", + "integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==", + "dev": true + }, + "node_modules/@types/sizzle": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.8.tgz", + "integrity": "sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==", + "dev": true + }, "node_modules/@types/sockjs": { "version": "0.3.36", "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", @@ -2303,6 +2392,16 @@ "@types/node": "*" } }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@webassemblyjs/ast": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", @@ -2544,6 +2643,19 @@ "node": ">=8.9" } }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -2608,6 +2720,30 @@ "ajv": "^6.9.1" } }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-html-community": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", @@ -2657,6 +2793,26 @@ "node": ">= 8" } }, + "node_modules/arch": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", + "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -2672,6 +2828,15 @@ "node": ">=8" } }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, "node_modules/asn1.js": { "version": "4.10.1", "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", @@ -2699,6 +2864,15 @@ "util": "^0.10.4" } }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, "node_modules/assert/node_modules/inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", @@ -2714,12 +2888,36 @@ "inherits": "2.0.3" } }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", + "dev": true + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "dev": true }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/autoprefixer": { "version": "10.4.19", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", @@ -2757,6 +2955,21 @@ "postcss": "^8.1.0" } }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", + "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", + "dev": true + }, "node_modules/axios": { "version": "1.6.8", "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", @@ -2867,6 +3080,15 @@ "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", "dev": true }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dev": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, "node_modules/big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", @@ -2888,6 +3110,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/blob-util": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", + "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==", + "dev": true + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, "node_modules/bn.js": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", @@ -3141,6 +3375,15 @@ "isarray": "^1.0.0" } }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -3168,6 +3411,15 @@ "node": ">= 0.8" } }, + "node_modules/cachedir": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.4.0.tgz", + "integrity": "sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/call-bind": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", @@ -3238,6 +3490,12 @@ } ] }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "dev": true + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -3263,6 +3521,15 @@ "node": "*" } }, + "node_modules/check-more-types": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", + "integrity": "sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -3296,6 +3563,21 @@ "node": ">=6.0" } }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, "node_modules/cipher-base": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", @@ -3318,6 +3600,27 @@ "node": ">= 10.0" } }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/cli-table3": { "version": "0.6.4", "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.4.tgz", @@ -3333,6 +3636,22 @@ "@colors/colors": "1.5.0" } }, + "node_modules/cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "dependencies": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -3418,6 +3737,15 @@ "node": ">= 10" } }, + "node_modules/common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -3908,6 +4236,197 @@ "node": ">=8.0.0" } }, + "node_modules/cypress": { + "version": "13.7.1", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.7.1.tgz", + "integrity": "sha512-4u/rpFNxOFCoFX/Z5h+uwlkBO4mWzAjveURi3vqdSu56HPvVdyGTxGw4XKGWt399Y1JwIn9E1L9uMXQpc0o55w==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@cypress/request": "^3.0.0", + "@cypress/xvfb": "^1.2.4", + "@types/sinonjs__fake-timers": "8.1.1", + "@types/sizzle": "^2.3.2", + "arch": "^2.2.0", + "blob-util": "^2.0.2", + "bluebird": "^3.7.2", + "buffer": "^5.7.1", + "cachedir": "^2.3.0", + "chalk": "^4.1.0", + "check-more-types": "^2.24.0", + "cli-cursor": "^3.1.0", + "cli-table3": "~0.6.1", + "commander": "^6.2.1", + "common-tags": "^1.8.0", + "dayjs": "^1.10.4", + "debug": "^4.3.4", + "enquirer": "^2.3.6", + "eventemitter2": "6.4.7", + "execa": "4.1.0", + "executable": "^4.1.1", + "extract-zip": "2.0.1", + "figures": "^3.2.0", + "fs-extra": "^9.1.0", + "getos": "^3.2.1", + "is-ci": "^3.0.1", + "is-installed-globally": "~0.4.0", + "lazy-ass": "^1.6.0", + "listr2": "^3.8.3", + "lodash": "^4.17.21", + "log-symbols": "^4.0.0", + "minimist": "^1.2.8", + "ospath": "^1.2.2", + "pretty-bytes": "^5.6.0", + "process": "^0.11.10", + "proxy-from-env": "1.0.0", + "request-progress": "^3.0.0", + "semver": "^7.5.3", + "supports-color": "^8.1.1", + "tmp": "~0.2.1", + "untildify": "^4.0.0", + "yauzl": "^2.10.0" + }, + "bin": { + "cypress": "bin/cypress" + }, + "engines": { + "node": "^16.0.0 || ^18.0.0 || >=20.0.0" + } + }, + "node_modules/cypress/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/cypress/node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/cypress/node_modules/execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/cypress/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cypress/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cypress/node_modules/human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true, + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/cypress/node_modules/proxy-from-env": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", + "integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==", + "dev": true + }, + "node_modules/cypress/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/dayjs": { + "version": "1.11.10", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", + "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==", + "dev": true + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -4185,6 +4704,16 @@ "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==", "dev": true }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dev": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -4242,6 +4771,15 @@ "node": ">= 0.8" } }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, "node_modules/enhanced-resolve": { "version": "5.16.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz", @@ -4255,6 +4793,19 @@ "node": ">=10.13.0" } }, + "node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/entities": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", @@ -4397,6 +4948,12 @@ "node": ">= 0.6" } }, + "node_modules/eventemitter2": { + "version": "6.4.7", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.7.tgz", + "integrity": "sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==", + "dev": true + }, "node_modules/eventemitter3": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", @@ -4445,6 +5002,18 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, + "node_modules/executable": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", + "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", + "dev": true, + "dependencies": { + "pify": "^2.2.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/express": { "version": "4.19.2", "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", @@ -4517,6 +5086,56 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/extract-zip/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "dev": true, + "engines": [ + "node >=0.6.0" + ] + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -4575,6 +5194,30 @@ "node": ">=0.8.0" } }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/file-loader": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", @@ -4735,6 +5378,15 @@ "node": ">=0.10.3" } }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -4878,6 +5530,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/getos": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz", + "integrity": "sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==", + "dev": true, + "dependencies": { + "async": "^3.2.0" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -4916,6 +5586,21 @@ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "dev": true }, + "node_modules/global-dirs": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", + "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", + "dev": true, + "dependencies": { + "ini": "2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -5291,6 +5976,20 @@ } } }, + "node_modules/http-signature": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz", + "integrity": "sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^2.0.2", + "sshpk": "^1.14.1" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/https-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", @@ -5459,6 +6158,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -5475,6 +6183,15 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "node_modules/ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/interpret": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", @@ -5517,6 +6234,18 @@ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, + "node_modules/is-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "dev": true, + "dependencies": { + "ci-info": "^3.2.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, "node_modules/is-core-module": { "version": "2.13.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", @@ -5574,6 +6303,22 @@ "node": ">=0.10.0" } }, + "node_modules/is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "dev": true, + "dependencies": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -5583,6 +6328,15 @@ "node": ">=0.12.0" } }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-plain-obj": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", @@ -5607,13 +6361,31 @@ "node": ">=0.10.0" } }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -5652,6 +6424,12 @@ "node": ">=0.10.0" } }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "dev": true + }, "node_modules/jest-worker": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", @@ -5702,6 +6480,12 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "dev": true + }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -5720,12 +6504,24 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true + }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -5750,6 +6546,21 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/jsprim": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", + "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + } + }, "node_modules/junk": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz", @@ -5862,6 +6673,15 @@ "shell-quote": "^1.8.1" } }, + "node_modules/lazy-ass": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", + "integrity": "sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==", + "dev": true, + "engines": { + "node": "> 0.8" + } + }, "node_modules/lilconfig": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", @@ -5877,6 +6697,33 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, + "node_modules/listr2": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz", + "integrity": "sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==", + "dev": true, + "dependencies": { + "cli-truncate": "^2.1.0", + "colorette": "^2.0.16", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rfdc": "^1.3.0", + "rxjs": "^7.5.1", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "enquirer": ">= 2.3.0 < 3" + }, + "peerDependenciesMeta": { + "enquirer": { + "optional": true + } + } + }, "node_modules/loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", @@ -5930,12 +6777,83 @@ "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", "dev": true }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "dev": true + }, "node_modules/lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", "dev": true }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", @@ -6510,6 +7428,12 @@ "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", "dev": true }, + "node_modules/ospath": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz", + "integrity": "sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==", + "dev": true + }, "node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -6537,6 +7461,21 @@ "node": ">=8" } }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-pipe": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-pipe/-/p-pipe-3.1.0.tgz", @@ -6723,6 +7662,18 @@ "node": ">=0.12" } }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "dev": true + }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -6741,6 +7692,15 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -7326,6 +8286,18 @@ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", "dev": true }, + "node_modules/pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/pretty-time": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/pretty-time/-/pretty-time-1.1.0.tgz", @@ -7378,6 +8350,12 @@ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "dev": true }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true + }, "node_modules/public-encrypt": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", @@ -7398,6 +8376,16 @@ "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "node_modules/punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", @@ -7428,6 +8416,12 @@ "node": ">=0.4.x" } }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -7649,6 +8643,15 @@ "node": ">= 0.10" } }, + "node_modules/request-progress": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", + "integrity": "sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==", + "dev": true, + "dependencies": { + "throttleit": "^1.0.0" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -7751,6 +8754,19 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/retry": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", @@ -7770,6 +8786,12 @@ "node": ">=0.10.0" } }, + "node_modules/rfdc": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.1.tgz", + "integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==", + "dev": true + }, "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -7818,6 +8840,15 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -8273,6 +9304,20 @@ "node": ">=8" } }, + "node_modules/slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/sockjs": { "version": "0.3.24", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", @@ -8362,6 +9407,31 @@ "node": ">= 6" } }, + "node_modules/sshpk": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", + "dev": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/stable": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", @@ -8683,6 +9753,21 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, + "node_modules/throttleit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.1.tgz", + "integrity": "sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, "node_modules/thunky": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", @@ -8701,6 +9786,15 @@ "node": ">=0.6.0" } }, + "node_modules/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "dev": true, + "engines": { + "node": ">=14.14" + } + }, "node_modules/to-arraybuffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", @@ -8737,6 +9831,39 @@ "node": ">=0.6" } }, + "node_modules/tough-cookie": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", + "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", + "dev": true, + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie/node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie/node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/tslib": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", @@ -8749,6 +9876,36 @@ "integrity": "sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw==", "dev": true }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "dev": true + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -8826,6 +9983,15 @@ "node": ">= 0.8" } }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/update-browserslist-db": { "version": "1.0.13", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", @@ -8884,6 +10050,16 @@ "qs": "^6.11.2" } }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "node_modules/util": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", @@ -8932,6 +10108,26 @@ "node": ">= 0.8" } }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/verror/node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true + }, "node_modules/vm-browserify": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", @@ -9512,6 +10708,16 @@ "engines": { "node": ">=12" } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } } } } diff --git a/package.json b/package.json index bc71771..0f86e63 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "@fortawesome/fontawesome-free": "^5.15.2", "axios": "^1.6.8", "bootstrap": "^4.0.0", + "cypress": "^13.7.1", "font-awesome": "^4.7.0", "jquery": "^3.2", "jquery-ui": "^1.12.1", diff --git a/tests/cypress/integration/example.cy.js b/tests/cypress/integration/example.cy.js index b93866c..fd65fc9 100644 --- a/tests/cypress/integration/example.cy.js +++ b/tests/cypress/integration/example.cy.js @@ -3,5 +3,15 @@ describe('Example Test', () => { cy.visit('/'); cy.contains('notaR'); + + + }); + it('shows exercicios link', () => { + cy.visit('/'); + + cy.contains('Exercícios').click(); + cy.url().should('include', '/exercicio') + + }); }); From d3281abe5d656bb8930f8e0126de69480745d87c Mon Sep 17 00:00:00 2001 From: Mali Oz Date: Fri, 29 Mar 2024 15:29:20 -0300 Subject: [PATCH 03/13] create admin with name --- app/Console/Commands/MigrateAdmin.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/Console/Commands/MigrateAdmin.php b/app/Console/Commands/MigrateAdmin.php index 6caab23..c06633d 100644 --- a/app/Console/Commands/MigrateAdmin.php +++ b/app/Console/Commands/MigrateAdmin.php @@ -44,10 +44,11 @@ public function handle() } User::create([ 'email' => 'admin@notar.br', + 'name' => 'Admin', 'is_admin' => true, 'password' => $this->argument('password') ]); - + $this->info('User admin@notar.br created!'); return 0; From a2655d42235cada9fa73c90aefee3387820e4916 Mon Sep 17 00:00:00 2001 From: Mali Oz Date: Fri, 29 Mar 2024 15:29:32 -0300 Subject: [PATCH 04/13] admin login test --- tests/cypress/integration/admin_login.cy.js | 33 +++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 tests/cypress/integration/admin_login.cy.js diff --git a/tests/cypress/integration/admin_login.cy.js b/tests/cypress/integration/admin_login.cy.js new file mode 100644 index 0000000..40fa9ed --- /dev/null +++ b/tests/cypress/integration/admin_login.cy.js @@ -0,0 +1,33 @@ +describe('Login test', () => { + const email = 'admin@notar.br'; + const password = 'novasenha'; + + beforeEach(() => { + const artisan = './vendor/bin/sail artisan' + // reset and seed the database prior to every test + // seed a user in the DB that we can control from our tests + cy.exec(`${artisan} migrate:fresh`) + cy.exec(`${artisan} migrate:admin ${password}`) + + }) + + it('Log in via login form', function () { + cy.visit('/') + + // Login link exists + cy.contains('Entrar').click(); + // Redirects to login + cy.url().should('include', '/login') + + // Fill up form + cy.get('input[name=email]').type(email) + // {enter} causes the form to submit + cy.get('input[name=password]').type(`${password}{enter}`) + + // Should be redirected to user page + cy.url().should('include', '/user/1') + + // UI should reflect this user being logged in + cy.get('h1').should('contain', 'Admin') + }) +}) From 5a5f59f820595caa29b8b1557411de3790b428c8 Mon Sep 17 00:00:00 2001 From: Mali Oz Date: Fri, 29 Mar 2024 15:31:25 -0300 Subject: [PATCH 05/13] remove cypress container --- docker-compose.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index c883091..82a5822 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -46,13 +46,6 @@ services: volumes: - './storage/app/public/arquivos:/arquivos' - './storage/app/temp:/temp' - cypress: - image: 'cypress/included' - volumes: - - '.:/var/www/html' - working_dir: '/var/www/html' - networks: - - sail networks: sail: driver: bridge From 9f7ed38d7c71d77dac719068c3e256047d571cbb Mon Sep 17 00:00:00 2001 From: Mali Oz Date: Fri, 29 Mar 2024 15:48:56 -0300 Subject: [PATCH 06/13] cypress laracasts --- composer.json | 1 + composer.lock | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 064d370..e5ad197 100644 --- a/composer.json +++ b/composer.json @@ -19,6 +19,7 @@ "require-dev": { "barryvdh/laravel-debugbar": "^3.6", "fakerphp/faker": "^1.9.1", + "laracasts/cypress": "^3.0", "laravel/breeze": "^2.0", "laravel/sail": "^1.29", "laravel/ui": "^4.0", diff --git a/composer.lock b/composer.lock index a5658ff..5294604 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "87e0211abe27da6cfe19c7bee8f1aa90", + "content-hash": "d1e9e55d313862befef90771a0dfb213", "packages": [ { "name": "brick/math", @@ -6117,6 +6117,65 @@ }, "time": "2020-07-09T08:09:16+00:00" }, + { + "name": "laracasts/cypress", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/laracasts/cypress.git", + "reference": "449f9d69da75091c77327093e5727a5c739a4cf8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laracasts/cypress/zipball/449f9d69da75091c77327093e5727a5c739a4cf8", + "reference": "449f9d69da75091c77327093e5727a5c739a4cf8", + "shasum": "" + }, + "require": { + "illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", + "php": "^8.0" + }, + "require-dev": { + "orchestra/testbench": "^6.0|^7.0|^8.0|^9.0", + "phpunit/phpunit": "^8.0|^9.5.10|^10.5", + "spatie/laravel-ray": "^1.29" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Laracasts\\Cypress\\CypressServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laracasts\\Cypress\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jeffrey Way", + "email": "jeffrey@laracasts.com", + "role": "Developer" + } + ], + "description": "Laravel Cypress Boilerplate", + "homepage": "https://github.com/laracasts/cypress", + "keywords": [ + "cypress", + "laracasts" + ], + "support": { + "issues": "https://github.com/laracasts/cypress/issues", + "source": "https://github.com/laracasts/cypress/tree/3.0.2" + }, + "time": "2024-03-19T14:07:37+00:00" + }, { "name": "laravel/breeze", "version": "v2.0.1", From b3e2570ded9b9fc786ca7220a823e09f444a050f Mon Sep 17 00:00:00 2001 From: Mali Oz Date: Fri, 29 Mar 2024 17:52:36 -0300 Subject: [PATCH 07/13] tests tests --- cypress.config.js | 2 +- tests/cypress/integration/admin_login.cy.js | 38 +++++++- .../integration/exercicio_create.cy.js | 97 +++++++++++++++++++ 3 files changed, 135 insertions(+), 2 deletions(-) create mode 100644 tests/cypress/integration/exercicio_create.cy.js diff --git a/cypress.config.js b/cypress.config.js index 62d3205..31f9c28 100644 --- a/cypress.config.js +++ b/cypress.config.js @@ -2,7 +2,7 @@ const { defineConfig } = require('cypress') module.exports = defineConfig({ chromeWebSecurity: false, - retries: 2, + retries: 0, defaultCommandTimeout: 5000, watchForFileChanges: false, videosFolder: 'tests/cypress/videos', diff --git a/tests/cypress/integration/admin_login.cy.js b/tests/cypress/integration/admin_login.cy.js index 40fa9ed..637f1b3 100644 --- a/tests/cypress/integration/admin_login.cy.js +++ b/tests/cypress/integration/admin_login.cy.js @@ -2,7 +2,7 @@ describe('Login test', () => { const email = 'admin@notar.br'; const password = 'novasenha'; - beforeEach(() => { + before(() => { const artisan = './vendor/bin/sail artisan' // reset and seed the database prior to every test // seed a user in the DB that we can control from our tests @@ -29,5 +29,41 @@ describe('Login test', () => { // UI should reflect this user being logged in cy.get('h1').should('contain', 'Admin') + + // Can see turmas + cy.contains('Turmas').click() + cy.url().should('include', '/turma') + cy.contains('Turmas') + cy.go('back') + + // Can see Users + cy.contains('Usuários').click() + cy.url().should('include', '/user') + cy.contains('Usuários') + cy.go('back') + + // Can see Exercícios + cy.contains('Exercícios').click() + cy.url().should('include', '/exercicio') + cy.contains('Exercícios') + cy.go('back') + + // Can see Arquivos + cy.contains('Arquivos').click() + cy.url().should('include', '/arquivos') + cy.contains('Arquivos') + cy.go('back') + + // Can see Relatórios + cy.contains('Relatórios').click() + cy.url().should('include', '/relatorio') + cy.contains('Relatórios') + cy.go('back') + + // Can see Impedimentos + cy.contains('Impedimentos').click() + cy.url().should('include', '/impedimentos') + cy.contains('Impedimentos') + cy.go('back') }) }) diff --git a/tests/cypress/integration/exercicio_create.cy.js b/tests/cypress/integration/exercicio_create.cy.js new file mode 100644 index 0000000..a8b4860 --- /dev/null +++ b/tests/cypress/integration/exercicio_create.cy.js @@ -0,0 +1,97 @@ +describe('Login test', () => { + const email = 'admin@notar.br'; + const password = 'novasenha'; + + const title = 'Exercício 1' + const description = 'Siga as instruções com atenção. Some x e y e salve na variável x, sem usar sum.' + const preconds = 'x <- 1; y <- 2; proibir(\'sum\')' + const [cond1, dica1] = ['proibidas()', 'no sum'] + const [cond2, dica2] = ['x == 3', 'x tem que ser a soma de x e y'] + + before(() => { + const artisan = './vendor/bin/sail artisan' + // reset and seed the database prior to every test + // seed a user in the DB that we can control from our tests + cy.exec(`${artisan} migrate:fresh`) + cy.exec(`${artisan} migrate:admin ${password}`) + + }) + + beforeEach('Log in via login form', function () { + cy.visit('/login') + + // Fill up form + cy.get('input[name=email]').type(email) + // {enter} causes the form to submit + cy.get('input[name=password]').type(`${password}{enter}`) + }) + + it('Create exercicio', function () { + // Can see Exercícios + cy.contains('Exercícios').click() + cy.url().should('include', '/exercicio') + cy.contains('Exercícios') + + cy.contains('Cadastrar exercicio').click() + + cy.contains('Criar novo exercício') + + // Fill form + cy.get('input[name="name"]').type(title) + .should('have.value', title) + cy.get('textarea[name="description"]').type(description) + .should('have.value', description) + cy.get('textarea[name="precondicoes"]').type(preconds) + .should('have.value', preconds) + + // Cond 1 + cy.get('input[name="condicoes[]"]').type(cond1) + .should('have.value', cond1) + cy.get('input[name="dicas[]"]').type(dica1) + .should('have.value', dica1) + cy.get('input[name="pesos[]"]').type('1') + .should('have.value', '1') + + cy.get('i.add-row').click() + cy.get('tr:nth-child(2) input[name="condicoes[]"]').type(cond2) + .should('have.value', cond2) + cy.get('tr:nth-child(2) input[name="dicas[]"]').type(dica2) + .should('have.value', dica2) + cy.get('tr:nth-child(2) input[name="pesos[]"]').type('1') + .should('have.value', '1') + + cy.contains('button', 'Criar').click() + + // Should redirect to exercicio + cy.url().should('include', '/exercicio/1') + }) + it('Responder ao exercício', function () { + cy.visit('/exercicio/1') + + cy.contains('h1', title) + cy.contains(description) + cy.contains('Editar este exercício') + cy.contains('Exportar este exercício') + cy.contains('Resposta') + + // Send valid answer + cy.get('div#editor').type('x <- x + y{enter}') + cy.contains('Sua nota: 100.0%') + }) + + it('Responder ao exercício com resposta errada', function () { + cy.visit('/exercicio/1') + // Send half-valid answer + cy.get('div#editor').type('x <- sum(x,y){enter}') + cy.contains(dica1) + cy.contains('Sua nota: 50.0%') + }) + + it('Responder ao exercício com erro de sintaxe', function () { + cy.visit('/exercicio/1') + // Send invalid answer + cy.get('div#editor').type('something{enter}') + cy.contains('erro') + cy.contains('Sua nota: 0.0%') + }) +}) From aa62da2a12ebe4369e5c699f3423f6f07bf02fcf Mon Sep 17 00:00:00 2001 From: Mali Oz Date: Wed, 10 Apr 2024 13:56:25 -0300 Subject: [PATCH 08/13] add instructions on cypress test --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index 46ec1e4..4b01715 100644 --- a/README.md +++ b/README.md @@ -45,5 +45,19 @@ docker exec -t notar_app_1 php artisan migrate docker exec -t notar_app_1 php artisan migrate:admin novasenha ``` +## Rodando os testes de integração + +**ATENÇÃO: ESSES TESTES DESTROEM SEU BANCO DE DADOS LOCAL. NÃO RODE EM PRODUÇÃO** + +Os testes foram escritos para ajudar no desenvolvimento da plataforma. Todos os dados do banco de dados são destruídos antes dos testes, para evitar conflitos. Para testar e desenvolver a plataforma, instale o notaR no seu ambiente local para testes, seguindo o guia acima. Além disso, é necessário instalar o `npm`. Com isso, para abrir a interface gráfica do `cypress`, basta executar o seguinte comando: + +``` +npx cypress run +``` + +Na interface gráfica, selecione **E2E Testing**, e um browser à sua escolha. + +Para mais detalhes, consulte a [documentação do Cypress](https://docs.cypress.io/). + ## Licença de uso O código fonte do notaR está disponível sob licença GPLv3. From ad70156951331716efa855b281923ec3d85cc54e Mon Sep 17 00:00:00 2001 From: Mali Oz Date: Wed, 10 Apr 2024 13:56:34 -0300 Subject: [PATCH 09/13] change names of tests --- tests/cypress/integration/{example.cy.js => 00_guest.cy.js} | 6 +----- .../integration/{admin_login.cy.js => 01_admin_login.cy.js} | 0 .../{exercicio_create.cy.js => 02_exercicio_create.cy.js} | 6 +++--- 3 files changed, 4 insertions(+), 8 deletions(-) rename tests/cypress/integration/{example.cy.js => 00_guest.cy.js} (86%) rename tests/cypress/integration/{admin_login.cy.js => 01_admin_login.cy.js} (100%) rename tests/cypress/integration/{exercicio_create.cy.js => 02_exercicio_create.cy.js} (95%) diff --git a/tests/cypress/integration/example.cy.js b/tests/cypress/integration/00_guest.cy.js similarity index 86% rename from tests/cypress/integration/example.cy.js rename to tests/cypress/integration/00_guest.cy.js index fd65fc9..6841d79 100644 --- a/tests/cypress/integration/example.cy.js +++ b/tests/cypress/integration/00_guest.cy.js @@ -1,17 +1,13 @@ -describe('Example Test', () => { +describe('Visit page as a guest', () => { it('shows a homepage', () => { cy.visit('/'); cy.contains('notaR'); - - }); it('shows exercicios link', () => { cy.visit('/'); cy.contains('Exercícios').click(); cy.url().should('include', '/exercicio') - - }); }); diff --git a/tests/cypress/integration/admin_login.cy.js b/tests/cypress/integration/01_admin_login.cy.js similarity index 100% rename from tests/cypress/integration/admin_login.cy.js rename to tests/cypress/integration/01_admin_login.cy.js diff --git a/tests/cypress/integration/exercicio_create.cy.js b/tests/cypress/integration/02_exercicio_create.cy.js similarity index 95% rename from tests/cypress/integration/exercicio_create.cy.js rename to tests/cypress/integration/02_exercicio_create.cy.js index a8b4860..10590f0 100644 --- a/tests/cypress/integration/exercicio_create.cy.js +++ b/tests/cypress/integration/02_exercicio_create.cy.js @@ -1,4 +1,4 @@ -describe('Login test', () => { +describe('Cria, resolve e corrige exercício', () => { const email = 'admin@notar.br'; const password = 'novasenha'; @@ -17,7 +17,7 @@ describe('Login test', () => { }) - beforeEach('Log in via login form', function () { + beforeEach('Log in', function () { cy.visit('/login') // Fill up form @@ -26,7 +26,7 @@ describe('Login test', () => { cy.get('input[name=password]').type(`${password}{enter}`) }) - it('Create exercicio', function () { + it('Cria exercício', function () { // Can see Exercícios cy.contains('Exercícios').click() cy.url().should('include', '/exercicio') From 038f21fc74fbf1ab45241ab367d153a068898335 Mon Sep 17 00:00:00 2001 From: Mali Oz Date: Wed, 10 Apr 2024 13:57:49 -0300 Subject: [PATCH 10/13] remove ; from eol --- tests/cypress/integration/00_guest.cy.js | 8 ++++---- tests/cypress/integration/01_admin_login.cy.js | 6 +++--- tests/cypress/integration/02_exercicio_create.cy.js | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/cypress/integration/00_guest.cy.js b/tests/cypress/integration/00_guest.cy.js index 6841d79..c9cfade 100644 --- a/tests/cypress/integration/00_guest.cy.js +++ b/tests/cypress/integration/00_guest.cy.js @@ -1,13 +1,13 @@ describe('Visit page as a guest', () => { it('shows a homepage', () => { - cy.visit('/'); + cy.visit('/') - cy.contains('notaR'); + cy.contains('notaR') }); it('shows exercicios link', () => { - cy.visit('/'); + cy.visit('/') - cy.contains('Exercícios').click(); + cy.contains('Exercícios').click() cy.url().should('include', '/exercicio') }); }); diff --git a/tests/cypress/integration/01_admin_login.cy.js b/tests/cypress/integration/01_admin_login.cy.js index 637f1b3..f0a3074 100644 --- a/tests/cypress/integration/01_admin_login.cy.js +++ b/tests/cypress/integration/01_admin_login.cy.js @@ -1,6 +1,6 @@ describe('Login test', () => { - const email = 'admin@notar.br'; - const password = 'novasenha'; + const email = 'admin@notar.br' + const password = 'novasenha' before(() => { const artisan = './vendor/bin/sail artisan' @@ -15,7 +15,7 @@ describe('Login test', () => { cy.visit('/') // Login link exists - cy.contains('Entrar').click(); + cy.contains('Entrar').click() // Redirects to login cy.url().should('include', '/login') diff --git a/tests/cypress/integration/02_exercicio_create.cy.js b/tests/cypress/integration/02_exercicio_create.cy.js index 10590f0..dcd666b 100644 --- a/tests/cypress/integration/02_exercicio_create.cy.js +++ b/tests/cypress/integration/02_exercicio_create.cy.js @@ -1,6 +1,6 @@ describe('Cria, resolve e corrige exercício', () => { - const email = 'admin@notar.br'; - const password = 'novasenha'; + const email = 'admin@notar.br' + const password = 'novasenha' const title = 'Exercício 1' const description = 'Siga as instruções com atenção. Some x e y e salve na variável x, sem usar sum.' From fbd025179cc0b8ce803f4fd01e1f26710c9f8335 Mon Sep 17 00:00:00 2001 From: Mali Oz Date: Wed, 10 Apr 2024 14:06:44 -0300 Subject: [PATCH 11/13] bug fix --- tests/cypress/integration/01_admin_login.cy.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/cypress/integration/01_admin_login.cy.js b/tests/cypress/integration/01_admin_login.cy.js index f0a3074..936e10c 100644 --- a/tests/cypress/integration/01_admin_login.cy.js +++ b/tests/cypress/integration/01_admin_login.cy.js @@ -50,7 +50,7 @@ describe('Login test', () => { // Can see Arquivos cy.contains('Arquivos').click() - cy.url().should('include', '/arquivos') + cy.url().should('include', '/arquivo') cy.contains('Arquivos') cy.go('back') @@ -62,7 +62,7 @@ describe('Login test', () => { // Can see Impedimentos cy.contains('Impedimentos').click() - cy.url().should('include', '/impedimentos') + cy.url().should('include', '/impedimento') cy.contains('Impedimentos') cy.go('back') }) From 512c59f8658ba941901b9250788fd323f08bec6d Mon Sep 17 00:00:00 2001 From: Mali Oz Date: Wed, 10 Apr 2024 14:07:20 -0300 Subject: [PATCH 12/13] submit answers as guest --- tests/cypress/integration/02_exercicio_create.cy.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tests/cypress/integration/02_exercicio_create.cy.js b/tests/cypress/integration/02_exercicio_create.cy.js index dcd666b..ee4a119 100644 --- a/tests/cypress/integration/02_exercicio_create.cy.js +++ b/tests/cypress/integration/02_exercicio_create.cy.js @@ -17,16 +17,13 @@ describe('Cria, resolve e corrige exercício', () => { }) - beforeEach('Log in', function () { + it('Cria exercício', function () { cy.visit('/login') // Fill up form cy.get('input[name=email]').type(email) // {enter} causes the form to submit cy.get('input[name=password]').type(`${password}{enter}`) - }) - - it('Cria exercício', function () { // Can see Exercícios cy.contains('Exercícios').click() cy.url().should('include', '/exercicio') @@ -64,14 +61,18 @@ describe('Cria, resolve e corrige exercício', () => { // Should redirect to exercicio cy.url().should('include', '/exercicio/1') + + cy.contains('h1', title) + cy.contains(description) + cy.contains('Editar este exercício') + cy.contains('Exportar este exercício') + cy.contains('Resposta') }) it('Responder ao exercício', function () { cy.visit('/exercicio/1') cy.contains('h1', title) cy.contains(description) - cy.contains('Editar este exercício') - cy.contains('Exportar este exercício') cy.contains('Resposta') // Send valid answer From e074c3ba7e38660df0572ab9e1a6d2dd55819ad8 Mon Sep 17 00:00:00 2001 From: Mali Oz Date: Wed, 10 Apr 2024 14:14:32 -0300 Subject: [PATCH 13/13] more details and links on cypress --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4b01715..2e465a9 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,9 @@ docker exec -t notar_app_1 php artisan migrate:admin novasenha **ATENÇÃO: ESSES TESTES DESTROEM SEU BANCO DE DADOS LOCAL. NÃO RODE EM PRODUÇÃO** -Os testes foram escritos para ajudar no desenvolvimento da plataforma. Todos os dados do banco de dados são destruídos antes dos testes, para evitar conflitos. Para testar e desenvolver a plataforma, instale o notaR no seu ambiente local para testes, seguindo o guia acima. Além disso, é necessário instalar o `npm`. Com isso, para abrir a interface gráfica do `cypress`, basta executar o seguinte comando: +Os testes foram escritos para ajudar no desenvolvimento da plataforma. Todos os dados do banco de dados são destruídos antes dos testes, para evitar conflitos. Os testes foram desenvolvidos em [Cypress](https://www.cypress.io/) usando o pacote de cypress para laravel [laracasts/cypress](https://github.com/laracasts/cypress). Alguns arquivos foram gerados automaticamente usando o comanto `php artisan cypress:boilerplate`. + +Para testar e desenvolver a plataforma, instale o notaR no seu ambiente local para testes, seguindo o guia acima. Além disso, é necessário instalar o `npm`. Com isso, para abrir a interface gráfica do `cypress`, basta executar o seguinte comando: ``` npx cypress run