From a7da74b993e42372851cf927234436e1dd3595ed Mon Sep 17 00:00:00 2001 From: Nick Taylor Date: Fri, 29 Jan 2021 07:34:01 -0500 Subject: [PATCH] Cleaning Test Runs for End to End (E2E) Tests (#12143) * Added custom seed task * Added a test for the initial login for the intial admin of a forem instance. * Renamed admin login seed data file. * Pulled functions out of main Cypress plugin file and import them now. * Added some comments. * Added a comment about Cypress tasks requiring a return value to be considered successful. * Moved admin_login_setup seed file to spec folder. * Made change requests in regards to rake task. * Fixed reference to SiteConfig * Created the seeder class to be shared for all seed files. * Added a missing param to function comment. * Fixed seeder require in e2e test seed file. * Fixed seeder require in seeds.rb. Why is Rails.root required? * Added an environment guard for not being production in the e2e seed task. * Made seeder require relative. * Trying something for the Elastic Search issue in CI. * Revert "Trying something for the Elastic Search issue in CI." This reverts commit 7cb2a963c8ac1f9242c612a1b9fe8ff814605df6. * Search indices are now removed via bundle exec rake search:destroy * Now rake search:destroy is used in the Cypress task for resetting data as well. * Moved Seeder class to app/lib * Added cypress-rails * Got two flows working with db rollbacks. * Trimmed down the e2e dataset for now. * Added a custom Cypress command to encompass test setup. * removed unused e2e rake task * added some user login/password e2e tests. * Added a note about Cypress not cleaning cookies, so we do for the moment. * Removed code no longer required. * Removed comment in test that is no longer pertinent to the test suite. * Removed data cleaning plugins as cypress rails gem handles it now. * Added @citizen428's recommendation got raising an error if trying to seed production. * Temporarily have paralleziation of e2e tests disabled to figure out cypres-rails/knapsack pro integration. * Doh! Forgot a semi-colon in the Travis config. * Added a comment about not integrating cypress-rails/knapsack pro right now. * Removed knapsack pro npm package for now as we aren't using it. * Reworded comment about cypress-rails/kanpsackpro. * Removed seeding for tags to follow for onboarding in e2e seed data. * Made pree2e script e2e:setup so it only runs explicitly when needed. * Renamed bin/e2e to bin/e2e-ci. * Created a new script for local e2e testing. * Removed RAILS_ENV as it's in the e2e-ci script already. * Fixed an auto corrected command. * Fixed wording in e2e script prompt. * Removed bundle exec rake data_updates:run that I had added. Doesn't appear to be necessary. * Added missing new lines. * Renamed e2e seed file and only use that one now. THere are no others. * Some script cleanup. * Added a check for the E2E environment so as to not pollute system tests. * Now e2e test server cleanup occurs when the server shuts down. * Put puts as this is really just for testing. * Put environment variable in the proper place for runnning bundle exec. * Added a check to only run for E2E tests. * Some bash script formatting. * Removed copy paste irrelevant comments. * Updated e2e server shutdown message. * Now a data-testid attribute is used for finding the user account errors panel. * Made test selectors ignore casing of text. * Removed prod paranoia check in e2e seed file. * Refactored spec to use new cy.loginUser(user) command. * Update app/lib/seeder.rb Co-authored-by: Michael Kohl * Fixed flakiness that @aitchiss was experiencing. * Rubocop fix. * Due to a Cypress issue, fixing cookie clearing with another tweak. * Bumped the wait time to 500ms if cookies don't clear. * Added a 'bundle check' to the bin/e2e script as suggested by @katiedavis. * Removed some white space Co-authored-by: Michael Kohl --- .travis.yml | 4 +- Gemfile | 1 + Gemfile.lock | 4 + app/lib/seeder.rb | 47 +++++ .../users/_account_set_password.html.erb | 2 +- app/views/users/_errors.html.erb | 2 +- app/views/users/confirm_destroy.html.erb | 2 +- bin/e2e | 24 ++- bin/e2e-ci | 4 + bin/e2e-setup | 9 + config/initializers/cypress_rails.rb | 30 ++++ cypress.dev.json | 8 +- cypress.json | 4 +- cypress/fixtures/logins/initialAdmin.json | 6 - .../fixtures/users/changePasswordUser.json | 4 + .../loginFlows/initialAdminLogin.spec.js | 68 -------- .../loginFlows/userChangePassword.spec.js | 77 +++++++++ .../integration/loginFlows/userLogin.spec.js | 36 ++++ cypress/plugins/index.js | 68 -------- cypress/support/commands.js | 39 +++++ db/seeds.rb | 38 +---- lib/tasks/e2e_seed.rake | 14 ++ package.json | 7 +- spec/support/seeds/seeds_e2e.rb | 86 ++++++++++ vendor/cache/cypress-rails-0.4.2.gem | Bin 0 -> 19456 bytes yarn.lock | 160 ++---------------- 26 files changed, 393 insertions(+), 351 deletions(-) create mode 100644 app/lib/seeder.rb create mode 100755 bin/e2e-ci create mode 100755 bin/e2e-setup create mode 100644 config/initializers/cypress_rails.rb delete mode 100644 cypress/fixtures/logins/initialAdmin.json create mode 100644 cypress/fixtures/users/changePasswordUser.json delete mode 100644 cypress/integration/loginFlows/initialAdminLogin.spec.js create mode 100644 cypress/integration/loginFlows/userChangePassword.spec.js create mode 100644 cypress/integration/loginFlows/userLogin.spec.js create mode 100644 lib/tasks/e2e_seed.rake create mode 100644 spec/support/seeds/seeds_e2e.rb create mode 100644 vendor/cache/cypress-rails-0.4.2.gem diff --git a/.travis.yml b/.travis.yml index 8e5be73a5..70e6d6f0b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -86,9 +86,7 @@ jobs: - bin/test-console-check - yarn build-storybook - bundle exec rake data_updates:run # required for at least creating the first admin user in e2e tests. - - yarn e2e:ci - # Dropping and recreating the database for Capybara/rspecs - # - curl -XDELETE "${ELASTICSEARCH_URL}/*" # resetting elastic search post e2e tests + - bin/e2e-ci - stage: Deploy name: Deploy DEV diff --git a/Gemfile b/Gemfile index 516d9058d..9946dc48f 100644 --- a/Gemfile +++ b/Gemfile @@ -141,6 +141,7 @@ group :development, :test do gem "amazing_print", "~> 1.2" # Great Ruby debugging companion: pretty print Ruby objects to visualize their structure gem "bullet", "~> 6.1" # help to kill N+1 queries and unused eager loading gem "capybara", "~> 3.35.1" # Capybara is an integration testing tool for rack based web applications + gem "cypress-rails", "~> 0.4.2" # For end to end tests (E2E) gem "dotenv-rails", "~> 2.7.6" # For loading ENV variables locally gem "faker", "~> 2.15" # A library for generating fake data such as names, addresses, and phone numbers gem "knapsack_pro", "~> 2.11.0" # Help parallelize Ruby spec builds diff --git a/Gemfile.lock b/Gemfile.lock index b0ac4e428..4a513fc35 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -202,6 +202,9 @@ GEM crack (0.4.5) rexml crass (1.0.6) + cypress-rails (0.4.2) + puma (>= 3.8.0) + railties (>= 5.2.0) dante (0.2.0) database_cleaner (1.8.5) database_cleaner-active_record (1.8.0) @@ -862,6 +865,7 @@ DEPENDENCIES cld (~> 0.8) cloudinary (~> 1.18) counter_culture (~> 2.7) + cypress-rails (~> 0.4.2) database_cleaner-active_record (~> 1.8.0) ddtrace (~> 0.45.0) derailed_benchmarks (~> 2.0) diff --git a/app/lib/seeder.rb b/app/lib/seeder.rb new file mode 100644 index 000000000..485ec2865 --- /dev/null +++ b/app/lib/seeder.rb @@ -0,0 +1,47 @@ +# rubocop:disable Rails/Output + +class Seeder + def initialize + if Rails.env.production? + puts "Can't run seeds in production" + + # rubocop:disable Rails/Exit + exit 1 + # rubocop:enable Rails/Exit + end + + @counter = 0 + end + + # Used when the block is idempotent by itself and needs no further checks. + def create(message) + @counter += 1 + puts " #{@counter}. #{message}." + yield + end + + def create_if_none(klass, count = nil) + @counter += 1 + plural = klass.name.pluralize + + if klass.none? + message = ["Creating", count, plural].compact.join(" ") + puts " #{@counter}. #{message}." + yield + else + puts " #{@counter}. #{plural} already exist. Skipping." + end + end + + def create_if_doesnt_exist(klass, attribute_name, attribute_value) + record = klass.find_by("#{attribute_name}": attribute_value) + if record.nil? + puts " #{klass} with #{attribute_name} = #{attribute_value} not found, proceeding..." + yield + else + puts " #{klass} with #{attribute_name} = #{attribute_value} found, skipping." + end + end +end + +# rubocop:enable Rails/Output diff --git a/app/views/users/_account_set_password.html.erb b/app/views/users/_account_set_password.html.erb index c3d360042..edbabd652 100644 --- a/app/views/users/_account_set_password.html.erb +++ b/app/views/users/_account_set_password.html.erb @@ -9,7 +9,7 @@ If you signed up with a social media account, please reset the password for your primary email address (<%= current_user.email %>) first.

- <%= form_with url: user_update_password_path do |f| %> + <%= form_with(url: user_update_password_path, data: { testid: "update-password-form" }) do |f| %>
<%= f.label :current_password, class: "crayons-field__label" %> <%= f.password_field :current_password, class: "crayons-textfield", autocomplete: "off" %> diff --git a/app/views/users/_errors.html.erb b/app/views/users/_errors.html.erb index e0f74daa9..fad1b51d9 100644 --- a/app/views/users/_errors.html.erb +++ b/app/views/users/_errors.html.erb @@ -1,4 +1,4 @@ -
+

<%= pluralize(errors.size, "error") %> <%= title_suffix %>: diff --git a/app/views/users/confirm_destroy.html.erb b/app/views/users/confirm_destroy.html.erb index 60a9026a1..58633366e 100644 --- a/app/views/users/confirm_destroy.html.erb +++ b/app/views/users/confirm_destroy.html.erb @@ -2,7 +2,7 @@

Destroy your account

- <%= form_tag user_full_delete_path, method: :delete, autocomplete: "off", id: "delete__account", class: 'flex flex-col gap-4 mb-4' do %> + <%= form_tag user_full_delete_path, method: :delete, autocomplete: "off", id: "delete__account", class: "flex flex-col gap-4 mb-4" do %> Deleting your account will:
  • delete your profile, along with your Twitter and/or GitHub associations. diff --git a/bin/e2e b/bin/e2e index c18936433..55a5dfe78 100755 --- a/bin/e2e +++ b/bin/e2e @@ -1,9 +1,19 @@ #!/bin/bash -if [ "$KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS" = "" ]; then - KNAPSACK_PRO_ENDPOINT=https://api-disabled-for-fork.knapsackpro.com \ - KNAPSACK_PRO_MAX_REQUEST_RETRIES=0 \ - KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS=disabled-for-fork \ - npx cypress run # run without parallelization -else - npx knapsack-pro-cypress # parallelization is available +printf "Doing a quick bundle check to make sure gems are all up to date.\n\n" +bundle check + +if [ $? -eq 1 ]; then + echo "Unable to launch end to end tests. Ensure that all your gems are installed and up to date." + exit; fi + +printf "\n" + +read -p "Do you need to set up your end to end (E2E) testing database? Answer yes if this is your first time running E2E tests on your local machine or you need to recreate your E2E test database. (y/n) " -n 1 -r + +if [[ $REPLY =~ ^[Yy]$ ]]; then + printf "\n\nSetting up the E2E database before running E2E tests...\n\n" + RAILS_ENV=test E2E=true bin/e2e-setup +fi + +CYPRESS_RAILS_CYPRESS_OPTS="--config-file cypress.dev.json" RAILS_ENV=test E2E=true bundle exec rake cypress:open diff --git a/bin/e2e-ci b/bin/e2e-ci new file mode 100755 index 000000000..becf7be34 --- /dev/null +++ b/bin/e2e-ci @@ -0,0 +1,4 @@ +#!/bin/bash +# As discussed in the engineering roundtable 2021/01/25, we will revisit cypress-rails knapsack pro integration +# for re-enabling parallelization of e2e tests later. +RAILS_ENV=test E2E=true bundle exec rake cypress:run \ No newline at end of file diff --git a/bin/e2e-setup b/bin/e2e-setup new file mode 100755 index 000000000..498f88800 --- /dev/null +++ b/bin/e2e-setup @@ -0,0 +1,9 @@ +if [ -z "$E2E" ]; then + echo "Setting up the end to end (E2E) test database did not run. You are not in an E2E test environment."; + exit 1; +fi + +bundle exec rails db:drop; +bundle exec rails db:create; +bundle exec rails db:schema:load; +bundle exec rails assets:precompile; diff --git a/config/initializers/cypress_rails.rb b/config/initializers/cypress_rails.rb new file mode 100644 index 000000000..14f2b96a7 --- /dev/null +++ b/config/initializers/cypress_rails.rb @@ -0,0 +1,30 @@ +# We want to check not only if we are in the test environment, but also if we are +# running E2E tests. Otherwise this will run when system tests run. +return unless Rails.env.test? && ENV["E2E"].present? + +# rubocop:disable Rails/Output + +CypressRails.hooks.before_server_start do + # Called once, before either the transaction or the server is started + puts "Starting up server for end to end tests." + Rails.application.load_tasks + Rake::Task["db:seed:e2e"].invoke +end + +CypressRails.hooks.after_transaction_start do + # Called after the transaction is started (at launch and after each reset) +end + +CypressRails.hooks.after_state_reset do + # Triggered after `/cypress_rails_reset_state` is called +end + +CypressRails.hooks.before_server_stop do + # Called once, at_exit + puts "Cleaning up and stopping server for end to end tests." + Rake::Task["search:destroy"].invoke + Rake::Task["db:truncate_all"].invoke + puts "The end to end test server shutdown gracefully." +end + +# rubocop:enable Rails/Output diff --git a/cypress.dev.json b/cypress.dev.json index e7a13a3c0..0967ef424 100644 --- a/cypress.dev.json +++ b/cypress.dev.json @@ -1,7 +1 @@ -{ - "baseUrl": "http://localhost:3000", - "env": { - "FOREM_OWNER_SECRET": "secret", - "ELASTICSEARCH_URL": "http://localhost:9200" - } -} +{} diff --git a/cypress.json b/cypress.json index 17ef242e7..72a92c99a 100644 --- a/cypress.json +++ b/cypress.json @@ -1,3 +1,5 @@ { - "baseUrl": "http://localhost:3000" + "screenshotsFolder": "tmp/cypress_screenshots", + "trashAssetsBeforeRuns": false, + "videosFolder": "tmp/cypress_videos" } diff --git a/cypress/fixtures/logins/initialAdmin.json b/cypress/fixtures/logins/initialAdmin.json deleted file mode 100644 index 209581eac..000000000 --- a/cypress/fixtures/logins/initialAdmin.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "Admin McAdmin", - "email": "admin@forem.local", - "username": "Admin_McAdmin", - "password": "password" -} diff --git a/cypress/fixtures/users/changePasswordUser.json b/cypress/fixtures/users/changePasswordUser.json new file mode 100644 index 000000000..02eaea13b --- /dev/null +++ b/cypress/fixtures/users/changePasswordUser.json @@ -0,0 +1,4 @@ +{ + "email": "change-password-user@forem.com", + "password": "password" +} diff --git a/cypress/integration/loginFlows/initialAdminLogin.spec.js b/cypress/integration/loginFlows/initialAdminLogin.spec.js deleted file mode 100644 index 79a6f03d5..000000000 --- a/cypress/integration/loginFlows/initialAdminLogin.spec.js +++ /dev/null @@ -1,68 +0,0 @@ -// Note if you are running these tests locallly, this test will fail -// if the first admin has already gone through the onboarding process. - -describe('Initial admin signup', () => { - beforeEach(() => { - cy.task('resetData'); - }); - - it('should sign up the initial Forem instance administrator', () => { - // This is the happy path. - cy.fixture('logins/initialAdmin.json').as('admin'); - - cy.log('baseUrl', Cypress.config().baseUrl); - - // Go to home page which redirects to the registration form. - cy.visit('/'); - - cy.findByTestId('registration-form').as('registrationForm'); - - cy.get('@registrationForm') - .findByLabelText(/Profile image/i) - .attachFile('images/admin-image.png'); - - cy.get('@admin').then((admin) => { - // Enter credentials for the initial administrator user - cy.get('@registrationForm') - .findByLabelText(/^Name$/i) - .type(admin.name); - cy.get('@registrationForm') - .findByLabelText(/Username/i) - .type(admin.username); - cy.get('@registrationForm') - .findByLabelText(/^Email$/i) - .type(admin.email); - cy.get('@registrationForm') - .findByLabelText('Password') - .type(admin.password); - cy.get('@registrationForm') - .findByLabelText(/^Password Confirmation$/i) - .type(admin.password); - cy.get('@registrationForm') - .findByLabelText(/New Forem Secret/i) - .type(Cypress.env('FOREM_OWNER_SECRET')); - - // Submit the form - cy.get('@registrationForm') - .findByText(/^Sign up$/) - .click(); - cy.log('Submitting signup form'); - - // The initial administrator user was create and is redirected to the confirm email screen. - cy.url().should( - 'eq', - Cypress.config().baseUrl + - '/confirm-email?email=' + - encodeURIComponent(admin.email), - ); - - cy.findByTestId('resend-confirmation-form').as('confirmationForm'); - cy.get('@confirmationForm') - .findByLabelText(/^Confirmation email address$/i) - .should('have.value', admin.email); - cy.get('@confirmationForm').findByText( - /^Resend confirmation instructions$/i, - ); - }); - }); -}); diff --git a/cypress/integration/loginFlows/userChangePassword.spec.js b/cypress/integration/loginFlows/userChangePassword.spec.js new file mode 100644 index 000000000..8075bd7dc --- /dev/null +++ b/cypress/integration/loginFlows/userChangePassword.spec.js @@ -0,0 +1,77 @@ +describe('User Change Password', () => { + beforeEach(() => { + cy.testSetup(); + cy.fixture('users/changePasswordUser.json').as('user'); + + cy.get('@user').then((user) => { + cy.loginUser(user).then(() => { + cy.visit('/settings/account'); + }); + }); + }); + + it('should change the password of a user', () => { + cy.fixture('users/changePasswordUser.json').as('user'); + + const newPassword = 'drowssap'; + + cy.findByTestId('update-password-form').as('updatePasswordForm'); + + cy.get('@user').then((user) => { + cy.get('@updatePasswordForm') + .findByText(/^Current Password$/i) + .type(user.password); + cy.get('@updatePasswordForm') + .findByText(/^Password$/i) + .type(newPassword); + cy.get('@updatePasswordForm') + .findByText(/^Confirm new password$/) + .type(newPassword); + + // Submit the form + cy.get('@updatePasswordForm').findByText('Set New Password').click(); + + cy.findByTestId('login-form').as('loginForm'); + + cy.get('@loginForm') + .findByText(/^Email$/) + .type(user.email); + cy.get('@loginForm') + .findByText(/^Password$/) + .type(newPassword); + }); + + // Submit the form + cy.get('@loginForm').findByText('Continue').click(); + + const { baseUrl } = Cypress.config(); + cy.url().should('equal', `${baseUrl}settings/account?signin=true`); + }); + + it('should give an error if the new password/confirm new password fields do not match when changing the password of a user', () => { + cy.fixture('users/changePasswordUser.json').as('user'); + + cy.get('@user').then((user) => { + cy.findByTestId('update-password-form').as('updatePasswordForm'); + + cy.get('@updatePasswordForm') + .findByText(/^Current Password$/i) + .type(user.password); + cy.get('@updatePasswordForm') + .findByText(/^Password$/i) + .type('some new password that is not the same'); + cy.get('@updatePasswordForm') + .findByText(/^Confirm new password$/) + .type('some other new password that is not the same'); + }); + + // Submit the form + cy.get('@updatePasswordForm') + .findByText(/^Set New Password$/) + .click(); + + cy.findByTestId('account-errors-panel').findByText( + /^Password doesn't match password confirmation$/, + ); + }); +}); diff --git a/cypress/integration/loginFlows/userLogin.spec.js b/cypress/integration/loginFlows/userLogin.spec.js new file mode 100644 index 000000000..7fc13de2c --- /dev/null +++ b/cypress/integration/loginFlows/userLogin.spec.js @@ -0,0 +1,36 @@ +describe('User Login', () => { + beforeEach(() => { + cy.testSetup(); + }); + + it('should login a user', () => { + cy.fixture('users/changePasswordUser.json').as('user'); + + // Go to home page + cy.visit('/'); + + // Click on the login button in the top header + cy.findAllByText('Log in').first().click(); + + // Ensure we are redirected to the login page + cy.url().should('contains', '/enter'); + + cy.findByTestId('login-form').as('loginForm'); + + cy.get('@user').then((user) => { + cy.get('@loginForm') + .findByText(/^Email$/) + .type(user.email); + cy.get('@loginForm') + .findByText(/^Password$/) + .type(user.password); + }); + + // Submit the form + cy.get('@loginForm').findByText('Continue').click(); + + // User should be redirected to onboarding + const { baseUrl } = Cypress.config(); + cy.url().should('equal', `${baseUrl}?signin=true`); + }); +}); diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js index 37cfe5c2d..cc92a687c 100644 --- a/cypress/plugins/index.js +++ b/cypress/plugins/index.js @@ -1,9 +1,6 @@ /// /* eslint-env node */ -const { spawn } = require('child_process'); -const fetch = require('node-fetch'); - // *********************************************************** // This example plugins/index.js can be used to load plugins // @@ -28,70 +25,5 @@ module.exports = (on, config) => { ...process.env, }; - on('task', { - async resetData() { - const clearSearchIndices = fetch(`${config.env.ELASTICSEARCH_URL}/*`, { - method: 'DELETE', - }); - - const truncateDB = new Promise((resolve, reject) => { - // Clear the DB for the next test run. - const child = spawn('bundle', ['exec', 'rails db:truncate_all']); - const errorChunks = []; - - child.stderr.on('data', (chunk) => - errorChunks.push(Buffer.from(chunk)), - ); - - child.on('error', (error) => { - reject(error); - }); - - child.on('exit', (status, _code) => { - if (status !== 0) { - const errorMessage = Buffer.concat(errorChunks).toString('UTF-8'); - - reject( - new Error( - `There was an error running "bundle exec rails db:truncate_all". The status was ${status} with the following error:\n${errorMessage}`, - ), - ); - } - - resolve(status === 0); - }); - }); - - const [clearSearchIndicesResponse, clearedDB = false] = await Promise.all( - [ - clearSearchIndices, - truncateDB.catch((error) => { - throw new Error(error); - }), - ], - ); - const { - acknowledged = false, - error, - } = await clearSearchIndicesResponse.json(); - - if (!acknowledged || error) { - throw new Error( - `There was an error clearing indices in Elastic Search:\n${ - error ? JSON.stringify(error, null, '\t') : '' - }`, - ); - } - - if (!clearedDB) { - throw new Error(`The database did not truncate successfully`); - } - - // Nothing to do, we're all good. - // Cypress tasks require a return value, so returning null. - return null; - }, - }); - return config; }; diff --git a/cypress/support/commands.js b/cypress/support/commands.js index ca4d256f3..bbb3ca996 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -23,3 +23,42 @@ // // -- This will overwrite an existing command -- // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) + +/** + * Runs necessary test setup to run a clean test. + */ +Cypress.Commands.add('testSetup', () => { + // Required for the moment because of https://github.com/cypress-io/cypress/issues/781 + cy.clearCookies(); + + cy.getCookies().then((cookie) => { + if (cookie.length) { + // Instead of always waiting, only wait if the cookies aren't + // cleared yet and attempt to clear again. + cy.wait(500); // eslint-disable-line cypress/no-unnecessary-waiting + cy.clearCookies(); + } + }); + + cy.request('/cypress_rails_reset_state'); +}); + +/** + * Logs in a user with the given email and password. + * + * @param credentials + * @param credentials.email {string} An email address + * @param credentials.password {string} A password + * + * @returns {Cypress.Chainable} A cypress request for signing in a user. + */ +Cypress.Commands.add('loginUser', ({ email, password }) => { + const encodedEmail = encodeURIComponent(email); + const encodedPassword = encodeURIComponent(password); + + return cy.request( + 'POST', + '/users/sign_in', + `utf8=%E2%9C%93&user%5Bemail%5D=${encodedEmail}&user%5Bpassword%5D=${encodedPassword}&user%5Bremember_me%5D=0&user%5Bremember_me%5D=1&commit=Continue`, + ); +}); diff --git a/db/seeds.rb b/db/seeds.rb index e2d52b3ef..f42e337f7 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -2,43 +2,9 @@ return if Rails.env.production? -# NOTE: when adding new data, please use this class to ensure the seed tasks +# NOTE: when adding new data, please use the Seeder class to ensure the seed tasks # stays idempotent. -class Seeder - def initialize - @counter = 0 - end - - # Used when the block is idempotent by itself and needs no further checks. - def create(message) - @counter += 1 - puts " #{@counter}. #{message}." - yield - end - - def create_if_none(klass, count = nil) - @counter += 1 - plural = klass.name.pluralize - - if klass.none? - message = ["Creating", count, plural].compact.join(" ") - puts " #{@counter}. #{message}." - yield - else - puts " #{@counter}. #{plural} already exist. Skipping." - end - end - - def create_if_doesnt_exist(klass, attribute_name, attribute_value) - record = klass.find_by("#{attribute_name}": attribute_value) - if record.nil? - puts " #{klass} with #{attribute_name} = #{attribute_value} not found, proceeding..." - yield - else - puts " #{klass} with #{attribute_name} = #{attribute_value} found, skipping." - end - end -end +require Rails.root.join("app/lib/seeder") # we use this to be able to increase the size of the seeded DB at will # eg.: `SEEDS_MULTIPLIER=2 rails db:seed` would double the amount of data diff --git a/lib/tasks/e2e_seed.rake b/lib/tasks/e2e_seed.rake new file mode 100644 index 000000000..6fb833c52 --- /dev/null +++ b/lib/tasks/e2e_seed.rake @@ -0,0 +1,14 @@ +# Thanks to https://stackoverflow.com/questions/19872271/adding-a-custom-seed-file/31815032#31815032 +SEED_DIR = Rails.root.join("spec/support/seeds/") + +namespace :db do + namespace :seed do + desc "Seed data for e2e tests" + task e2e: :environment do + raise "Attempting to seed production environment, aborting!" if Rails.env.production? + + filename = SEED_DIR.join("seeds_e2e.rb") + load(filename) if File.exist?(filename) + end + end +end diff --git a/package.json b/package.json index 0aa9f651d..4d54f3df5 100644 --- a/package.json +++ b/package.json @@ -25,10 +25,7 @@ "test": "jest app/javascript/ bin/ --coverage", "test:watch": "jest app/javascript/ bin/ --watch", "postcss": "postcss public/assets/*.css -d public/assets 2> postcss_error.log", - "e2e": "cypress open --config-file cypress.dev.json", - "e2e:runner": "bin/e2e", - "e2e:server": "bin/rails s -p 3000 -b 0.0.0.0", - "e2e:ci": "start-server-and-test e2e:server http://localhost:3000 e2e:runner" + "e2e": "bin/e2e" }, "husky": { "hooks": { @@ -88,7 +85,6 @@ }, "homepage": "https://github.com/thepracticaldev/dev.to#readme", "devDependencies": { - "@knapsack-pro/cypress": "^4.2.1", "@stoplight/spectral": "5.8.0", "@storybook/addon-a11y": "^6.1.15", "@storybook/addon-actions": "^6.1.15", @@ -135,7 +131,6 @@ "jsdom": "^16.4.0", "lint-staged": "^10.5.3", "markdown-loader": "^6.0.0", - "node-fetch": "^2.6.1", "prettier": "^2.2.1", "redoc-cli": "0.10.2", "sass": "1.32.5", diff --git a/spec/support/seeds/seeds_e2e.rb b/spec/support/seeds/seeds_e2e.rb new file mode 100644 index 000000000..d6357329d --- /dev/null +++ b/spec/support/seeds/seeds_e2e.rb @@ -0,0 +1,86 @@ +return unless Rails.env.test? && ENV["E2E"].present? + +# NOTE: when adding new data, please use the Seeder class to ensure the seed tasks +# stays idempotent. +require Rails.root.join("app/lib/seeder") + +seeder = Seeder.new + +############################################################################## +# Default development site config if different from production scenario + +SiteConfig.public = true +SiteConfig.waiting_on_first_user = false + +seeder.create_if_none(Organization) do + 3.times do + Organization.create!( + name: Faker::TvShows::SiliconValley.company, + summary: Faker::Company.bs, + remote_profile_image_url: logo = Faker::Company.logo, + nav_image: logo, + url: Faker::Internet.url, + slug: "org#{rand(10_000)}", + github_username: "org#{rand(10_000)}", + twitter_username: "org#{rand(10_000)}", + bg_color_hex: Faker::Color.hex_color, + text_color_hex: Faker::Color.hex_color, + ) + end +end + +############################################################################## + +# NOTE: @citizen428 For the time being we want all current DEV profile fields. +# The CSV import is idempotent by itself, since it uses find_or_create_by. +seeder.create("Creating DEV profile fields") do + dev_fields_csv = Rails.root.join("lib/data/dev_profile_fields.csv") + ProfileFields::ImportFromCsv.call(dev_fields_csv) +end + +############################################################################## + +seeder.create_if_doesnt_exist(User, "email", "admin@forem.local") do + user = User.create!( + name: "Admin McAdmin", + email: "admin@forem.local", + username: "Admin_McAdmin", + summary: Faker::Lorem.paragraph_by_chars(number: 199, supplemental: false), + profile_image: File.open(Rails.root.join("app/assets/images/#{rand(1..40)}.png")), + website_url: Faker::Internet.url, + email_comment_notifications: false, + email_follower_notifications: false, + confirmed_at: Time.current, + password: "password", + password_confirmation: "password", + saw_onboarding: true, + checked_code_of_conduct: true, + checked_terms_and_conditions: true, + ) + + user.add_role(:super_admin) + user.add_role(:single_resource_admin, Config) +end + +############################################################################## + +seeder.create_if_doesnt_exist(User, "email", "change-password-user@forem.com") do + User.create!( + name: "Change Password User", + email: "change-password-user@forem.com", + username: "changepassworduser", + summary: Faker::Lorem.paragraph_by_chars(number: 199, supplemental: false), + profile_image: File.open(Rails.root.join("app/assets/images/#{rand(1..40)}.png")), + website_url: Faker::Internet.url, + email_comment_notifications: false, + email_follower_notifications: false, + confirmed_at: Time.current, + password: "password", + password_confirmation: "password", + saw_onboarding: true, + checked_code_of_conduct: true, + checked_terms_and_conditions: true, + ) +end + +############################################################################## diff --git a/vendor/cache/cypress-rails-0.4.2.gem b/vendor/cache/cypress-rails-0.4.2.gem new file mode 100644 index 0000000000000000000000000000000000000000..cbfa8f095f2a8ce221e68e1ae15b8eb118c9ad53 GIT binary patch literal 19456 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 literal 0 HcmV?d00001 diff --git a/yarn.lock b/yarn.lock index 7504d0c42..dce5c7190 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1092,15 +1092,6 @@ debug "^3.1.0" lodash.once "^4.1.1" -"@dabh/diagnostics@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@dabh/diagnostics/-/diagnostics-2.0.2.tgz#290d08f7b381b8f94607dc8f471a12c675f9db31" - integrity sha512-+A1YivoVDNNVCdfozHSR8v/jyuuLTMXwjWuxPFlFlUapXoGc+Gj9mDlTDDfrwl7rXCl2tNZ0kE8sIBO6YOn96Q== - dependencies: - colorspace "1.1.x" - enabled "2.0.x" - kuler "^2.0.0" - "@emotion/babel-utils@^0.6.4": version "0.6.10" resolved "https://registry.yarnpkg.com/@emotion/babel-utils/-/babel-utils-0.6.10.tgz#83dbf3dfa933fae9fc566e54fbb45f14674c6ccc" @@ -1510,25 +1501,6 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" -"@knapsack-pro/core@^3.1.1": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@knapsack-pro/core/-/core-3.1.1.tgz#fe6f8c8c970cf3b80cc5410ae22f66f3c899ccf2" - integrity sha512-yn5PrrM7lAXMr+fr44COOvszzy19ZWoKwD9toRQoZICARfaYGXnYxxBEzdoxkOKk3tJTcYyHGNLc7pn94VNmbg== - dependencies: - axios "0.21.1" - axios-retry "^3.1.9" - winston "^3.3.3" - -"@knapsack-pro/cypress@^4.2.1": - version "4.2.1" - resolved "https://registry.yarnpkg.com/@knapsack-pro/cypress/-/cypress-4.2.1.tgz#0eef46caf4c21c7c3fe198d1ef08a5eabdd6e37c" - integrity sha512-r2mdSTWj433GtoBwVFyP/bd1AzUxtY4Txr6H0qaUsBqEKWQ/YkEUQTk5mfQbeJeIl0ZbkTSKqQsRDu+VXqR9wg== - dependencies: - "@knapsack-pro/core" "^3.1.1" - glob "^7.1.6" - minimist "^1.2.5" - uuid "^8.3.1" - "@mdx-js/loader@^1.6.19": version "1.6.22" resolved "https://registry.yarnpkg.com/@mdx-js/loader/-/loader-1.6.22.tgz#d9e8fe7f8185ff13c9c8639c048b123e30d322c4" @@ -4039,7 +4011,7 @@ async@^2.6.2: dependencies: lodash "^4.17.14" -async@^3.0.0, async@^3.1.0, async@^3.2.0: +async@^3.0.0, async@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720" integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw== @@ -4106,20 +4078,6 @@ axe-core@^4.0.1, axe-core@^4.0.2: resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.1.1.tgz#70a7855888e287f7add66002211a423937063eaf" integrity sha512-5Kgy8Cz6LPC9DJcNb3yjAXTu3XihQgEdnIg50c//zOC/MyLP0Clg+Y8Sh9ZjjnvBrDZU4DgXS9C3T9r4/scGZQ== -axios-retry@^3.1.9: - version "3.1.9" - resolved "https://registry.yarnpkg.com/axios-retry/-/axios-retry-3.1.9.tgz#6c30fc9aeb4519aebaec758b90ef56fa03fe72e8" - integrity sha512-NFCoNIHq8lYkJa6ku4m+V1837TP6lCa7n79Iuf8/AqATAHYB0ISaAS1eyIenDOfHOLtym34W65Sjke2xjg2fsA== - dependencies: - is-retry-allowed "^1.1.0" - -axios@0.21.1, axios@^0.21.1: - version "0.21.1" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8" - integrity sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA== - dependencies: - follow-redirects "^1.10.0" - axios@^0.18.0: version "0.18.1" resolved "https://registry.yarnpkg.com/axios/-/axios-0.18.1.tgz#ff3f0de2e7b5d180e757ad98000f1081b87bcea3" @@ -4128,6 +4086,13 @@ axios@^0.18.0: follow-redirects "1.5.10" is-buffer "^2.0.2" +axios@^0.21.1: + version "0.21.1" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8" + integrity sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA== + dependencies: + follow-redirects "^1.10.0" + axobject-query@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" @@ -6191,14 +6156,6 @@ color-string@^1.4.0, color-string@^1.5.2, color-string@^1.5.4: color-name "^1.0.0" simple-swizzle "^0.2.2" -color@3.0.x: - version "3.0.0" - resolved "https://registry.yarnpkg.com/color/-/color-3.0.0.tgz#d920b4328d534a3ac8295d68f7bd4ba6c427be9a" - integrity sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w== - dependencies: - color-convert "^1.9.1" - color-string "^1.5.2" - color@^0.11.0: version "0.11.4" resolved "https://registry.yarnpkg.com/color/-/color-0.11.4.tgz#6d7b5c74fb65e841cd48792ad1ed5e07b904d764" @@ -6237,19 +6194,11 @@ colorette@^1.2.1: resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b" integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw== -colors@^1.1.2, colors@^1.2.1: +colors@^1.1.2: version "1.4.0" resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== -colorspace@1.1.x: - version "1.1.2" - resolved "https://registry.yarnpkg.com/colorspace/-/colorspace-1.1.2.tgz#e0128950d082b86a2168580796a0aa5d6c68d8c5" - integrity sha512-vt+OoIP2d76xLhjwbBaucYlNSpPsrJWPlBTtwCpQKIu6/CSMutyzX93O/Do0qzpH3YoHEes8YEFXyZ797rEhzQ== - dependencies: - color "3.0.x" - text-hex "1.0.x" - combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -7736,11 +7685,6 @@ emotion@^9.1.2, emotion@^9.1.3, emotion@^9.2.12: babel-plugin-emotion "^9.2.11" create-emotion "^9.2.12" -enabled@2.0.x: - version "2.0.0" - resolved "https://registry.yarnpkg.com/enabled/-/enabled-2.0.0.tgz#f9dd92ec2d6f4bbc0d5d1e64e21d61cd4665e7c2" - integrity sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ== - encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" @@ -8544,7 +8488,7 @@ fast-memoize@^2.5.1: resolved "https://registry.yarnpkg.com/fast-memoize/-/fast-memoize-2.5.2.tgz#79e3bb6a4ec867ea40ba0e7146816f6cdce9b57e" integrity sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw== -fast-safe-stringify@^2.0.4, fast-safe-stringify@^2.0.7: +fast-safe-stringify@^2.0.7: version "2.0.7" resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743" integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA== @@ -8584,11 +8528,6 @@ fd-slicer@~1.1.0: dependencies: pend "~1.2.0" -fecha@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.0.tgz#3ffb6395453e3f3efff850404f0a59b6747f5f41" - integrity sha512-aN3pcx/DSmtyoovUudctc8+6Hl4T+hI9GBBHLjA76jdZl7+b1sgh5g4k+u/GL3dTy1/pnYzKp69FpJ0OicE3Wg== - figgy-pudding@^3.5.1: version "3.5.2" resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" @@ -8819,11 +8758,6 @@ flush-write-stream@^1.0.0: inherits "^2.0.3" readable-stream "^2.3.6" -fn.name@1.x.x: - version "1.1.0" - resolved "https://registry.yarnpkg.com/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc" - integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw== - focus-lock@^0.8.1: version "0.8.1" resolved "https://registry.yarnpkg.com/focus-lock/-/focus-lock-0.8.1.tgz#bb36968abf77a2063fa173cb6c47b12ac8599d33" @@ -10753,11 +10687,6 @@ is-resolvable@^1.0.0: resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== -is-retry-allowed@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" - integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== - is-root@2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.1.0.tgz#809e18129cf1129644302a4f8544035d51984a9c" @@ -11706,11 +11635,6 @@ klona@^2.0.4: resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.4.tgz#7bb1e3affb0cb8624547ef7e8f6708ea2e39dfc0" integrity sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA== -kuler@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3" - integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A== - language-subtag-registry@~0.3.2: version "0.3.21" resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz#04ac218bea46f04cb039084602c6da9e788dd45a" @@ -12125,17 +12049,6 @@ log-update@^4.0.0: slice-ansi "^4.0.0" wrap-ansi "^6.2.0" -logform@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/logform/-/logform-2.2.0.tgz#40f036d19161fc76b68ab50fdc7fe495544492f2" - integrity sha512-N0qPlqfypFx7UHNn4B3lzS/b0uLqt2hmuoa+PpuXNYgozdJYAyauF5Ky0BWVjrxDlMWiT3qN4zPq3vVAfZy7Yg== - dependencies: - colors "^1.2.1" - fast-safe-stringify "^2.0.4" - fecha "^4.2.0" - ms "^2.1.1" - triple-beam "^1.3.0" - loglevel@^1.6.8: version "1.7.1" resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197" @@ -12919,7 +12832,7 @@ node-fetch-h2@^2.3.0: dependencies: http2-client "^1.2.5" -node-fetch@2.6, node-fetch@2.6.1, node-fetch@^2.6.0, node-fetch@^2.6.1: +node-fetch@2.6, node-fetch@2.6.1, node-fetch@^2.6.0: version "2.6.1" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== @@ -13370,13 +13283,6 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0: dependencies: wrappy "1" -one-time@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/one-time/-/one-time-1.0.0.tgz#e06bc174aed214ed58edede573b433bbf827cb45" - integrity sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g== - dependencies: - fn.name "1.x.x" - onecolor@^3.0.4: version "3.1.0" resolved "https://registry.yarnpkg.com/onecolor/-/onecolor-3.1.0.tgz#b72522270a49569ac20d244b3cd40fe157fda4d2" @@ -16061,7 +15967,7 @@ read-pkg@^5.2.0: parse-json "^5.0.0" type-fest "^0.6.0" -"readable-stream@1 || 2", readable-stream@2, readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@^2.3.7, readable-stream@~2.3.6: +"readable-stream@1 || 2", readable-stream@2, readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -16084,7 +15990,7 @@ readable-stream@1.1.x: isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: +readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== @@ -17549,11 +17455,6 @@ stable@^0.1.8: resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== -stack-trace@0.0.x: - version "0.0.10" - resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" - integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA= - stack-utils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.3.tgz#cd5f030126ff116b78ccb3c027fe302713b61277" @@ -18213,11 +18114,6 @@ test-exclude@^6.0.0: glob "^7.1.4" minimatch "^3.0.4" -text-hex@1.0.x: - version "1.0.0" - resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5" - integrity sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg== - text-table@0.2, text-table@0.2.0, text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -18443,11 +18339,6 @@ trim@0.0.1: resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd" integrity sha1-WFhUf2spB1fulczMZm+1AITEYN0= -triple-beam@^1.2.0, triple-beam@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9" - integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw== - trough@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406" @@ -18991,7 +18882,7 @@ uuid@^3.3.2, uuid@^3.4.0: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== -uuid@^8.0.0, uuid@^8.3.0, uuid@^8.3.1: +uuid@^8.0.0, uuid@^8.3.0: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== @@ -19407,29 +19298,6 @@ widest-line@^3.1.0: dependencies: string-width "^4.0.0" -winston-transport@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.4.0.tgz#17af518daa690d5b2ecccaa7acf7b20ca7925e59" - integrity sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw== - dependencies: - readable-stream "^2.3.7" - triple-beam "^1.2.0" - -winston@^3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/winston/-/winston-3.3.3.tgz#ae6172042cafb29786afa3d09c8ff833ab7c9170" - integrity sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw== - dependencies: - "@dabh/diagnostics" "^2.0.2" - async "^3.1.0" - is-stream "^2.0.0" - logform "^2.2.0" - one-time "^1.0.0" - readable-stream "^3.4.0" - stack-trace "0.0.x" - triple-beam "^1.3.0" - winston-transport "^4.4.0" - wolfy87-eventemitter@~5.2.8: version "5.2.9" resolved "https://registry.yarnpkg.com/wolfy87-eventemitter/-/wolfy87-eventemitter-5.2.9.tgz#e879f770b30fbb6512a8afbb330c388591099c2a"