From 0f785b71736333bde1dc2aba96fd2d90bea83e57 Mon Sep 17 00:00:00 2001 From: Kailash Nadh Date: Mon, 14 Oct 2024 10:30:01 +0530 Subject: [PATCH] Fix Cypress tests to work with new auth and other UI changes. --- frontend/cypress.config.js | 8 +- frontend/cypress/e2e/archive.cy.js | 10 +- frontend/cypress/e2e/bounces.cy.js | 6 +- frontend/cypress/e2e/campaigns.cy.js | 34 ++--- frontend/cypress/e2e/forms.cy.js | 17 +-- frontend/cypress/e2e/import.cy.js | 46 ++++--- frontend/cypress/e2e/lists.cy.js | 17 +-- frontend/cypress/e2e/settings.cy.js | 2 +- frontend/cypress/e2e/subscribers.cy.js | 62 ++++----- frontend/cypress/e2e/templates.cy.js | 18 ++- frontend/cypress/support/commands.js | 17 ++- frontend/package.json | 4 +- frontend/src/views/Subscribers.vue | 5 +- frontend/yarn.lock | 171 ++++++++++++++++--------- 14 files changed, 227 insertions(+), 190 deletions(-) diff --git a/frontend/cypress.config.js b/frontend/cypress.config.js index 645ef328..c13f90b6 100644 --- a/frontend/cypress.config.js +++ b/frontend/cypress.config.js @@ -1,4 +1,4 @@ -const { defineConfig } = require('cypress') +const { defineConfig } = require('cypress'); module.exports = defineConfig({ env: { @@ -16,8 +16,8 @@ module.exports = defineConfig({ // We've imported your old cypress plugins here. // You may want to clean this up later by importing these. setupNodeEvents(on, config) { - return require('./cypress/plugins/index.js')(on, config) + return require('./cypress/plugins/index.js')(on, config); }, - baseUrl: 'http://localhost:9000/admin', + baseUrl: 'http://localhost:9000', }, -}) +}); diff --git a/frontend/cypress/e2e/archive.cy.js b/frontend/cypress/e2e/archive.cy.js index 20875ee1..cd61f24e 100644 --- a/frontend/cypress/e2e/archive.cy.js +++ b/frontend/cypress/e2e/archive.cy.js @@ -3,18 +3,18 @@ const apiUrl = Cypress.env('apiUrl'); describe('Archive', () => { it('Opens campaigns page', () => { cy.resetDB(); - cy.loginAndVisit('/campaigns'); + cy.loginAndVisit('/admin/campaigns'); cy.wait(500); }); it('Clones campaign', () => { - cy.loginAndVisit('/campaigns'); + cy.loginAndVisit('/admin/campaigns'); cy.get('[data-cy=btn-clone]').first().click(); cy.get('.modal input').clear().type('clone').click(); cy.get('.modal button.is-primary').click(); cy.wait(250); - cy.loginAndVisit('/campaigns'); + cy.loginAndVisit('/admin/campaigns'); cy.get('[data-cy=btn-clone]').first().click(); cy.get('.modal input').clear().type('clone2').click(); cy.get('.modal button.is-primary').click(); @@ -35,7 +35,7 @@ describe('Archive', () => { }); it('Enables archive on one campaign (no slug)', () => { - cy.loginAndVisit('/campaigns'); + cy.loginAndVisit('/admin/campaigns'); cy.wait(250); cy.get('td[data-label=Status] a').eq(0).click(); @@ -51,7 +51,7 @@ describe('Archive', () => { }); it('Enables archive on one campaign', () => { - cy.loginAndVisit('/campaigns'); + cy.loginAndVisit('/admin/campaigns'); cy.wait(250); cy.get('td[data-label=Status] a').eq(1).click(); diff --git a/frontend/cypress/e2e/bounces.cy.js b/frontend/cypress/e2e/bounces.cy.js index b9146572..aadf552c 100644 --- a/frontend/cypress/e2e/bounces.cy.js +++ b/frontend/cypress/e2e/bounces.cy.js @@ -1,12 +1,12 @@ const apiUrl = Cypress.env('apiUrl'); describe('Bounces', () => { - let subs = []; + const subs = []; it('Enable bounces', () => { cy.resetDB(); - cy.loginAndVisit('/settings'); + cy.loginAndVisit('/admin/settings'); cy.get('.b-tabs nav a').eq(6).click(); cy.get('[data-cy=btn-enable-bounce] .switch').click(); cy.get('[data-cy=btn-enable-bounce-webhook] .switch').click(); @@ -55,7 +55,7 @@ describe('Bounces', () => { expect(resp.status).to.eq(400); }); - cy.loginAndVisit('/subscribers/bounces'); + cy.loginAndVisit('/admin/subscribers/bounces'); }); }); }); diff --git a/frontend/cypress/e2e/campaigns.cy.js b/frontend/cypress/e2e/campaigns.cy.js index ac664c5b..76fa0f5d 100644 --- a/frontend/cypress/e2e/campaigns.cy.js +++ b/frontend/cypress/e2e/campaigns.cy.js @@ -4,10 +4,9 @@ const headers = '[{"X-Custom": "Custom-Value"}]'; describe('Campaigns', () => { it('Opens campaigns page', () => { cy.resetDB(); - cy.loginAndVisit('/campaigns'); + cy.loginAndVisit('/admin/campaigns'); }); - it('Counts campaigns', () => { cy.get('tbody td[data-label=Status]').should('have.length', 1); }); @@ -34,7 +33,7 @@ describe('Campaigns', () => { cy.wait(500); // Re-open and check that the file still exists. - cy.loginAndVisit('/campaigns'); + cy.loginAndVisit('/admin/campaigns'); cy.get('td[data-label=Status] a').eq(0).click(); cy.get('.b-tabs nav a').eq(1).click(); cy.get('div.field[data-cy=media]').contains('example'); @@ -115,10 +114,9 @@ describe('Campaigns', () => { cy.get('tbody td[data-label=Status] .tag.scheduled'); }); - it('Switches formats', () => { - cy.resetDB() - cy.loginAndVisit('/campaigns'); + cy.resetDB(); + cy.loginAndVisit('/admin/campaigns'); const formats = ['html', 'markdown', 'plain']; const htmlBody = 'hello \{\{ .Subscriber.Name \}\} from {\{ .Subscriber.Attribs.city \}\}'; const plainBody = 'hello Demo Subscriber from Bengaluru'; @@ -132,9 +130,8 @@ describe('Campaigns', () => { }); cy.get('button[data-cy=btn-save]').click(); - formats.forEach((c) => { - cy.loginAndVisit('/campaigns'); + cy.loginAndVisit('/admin/campaigns'); cy.get('td[data-label=Status] a').click(); // Switch to content tab. @@ -147,7 +144,7 @@ describe('Campaigns', () => { // Check content. cy.get('button[data-cy=btn-preview]').click(); cy.wait(500); - cy.get("#iframe").then(($f) => { + cy.get('#iframe').then(($f) => { if (c === 'plain') { return; } @@ -158,9 +155,8 @@ describe('Campaigns', () => { }); }); - it('Clones campaign', () => { - cy.loginAndVisit('/campaigns'); + cy.loginAndVisit('/admin/campaigns'); for (let n = 0; n < 3; n++) { // Clone the campaign. cy.get('[data-cy=btn-clone]').first().click(); @@ -175,7 +171,6 @@ describe('Campaigns', () => { } }); - it('Searches campaigns', () => { cy.get('input[name=query]').clear().type('clone2{enter}'); cy.get('tbody tr').its('length').should('eq', 1); @@ -183,7 +178,6 @@ describe('Campaigns', () => { cy.get('input[name=query]').clear().type('{enter}'); }); - it('Deletes campaign', () => { // Delete all visible lists. cy.get('tbody tr').each(() => { @@ -195,7 +189,6 @@ describe('Campaigns', () => { cy.get('table tr.is-empty'); }); - it('Adds new campaigns', () => { const lists = [[1], [1, 2]]; const cTypes = ['richtext', 'html', 'markdown', 'plain']; @@ -243,8 +236,7 @@ describe('Campaigns', () => { expect(data.headers[0][`X-Header-${n}`]).to.equal(`Value-${n}`); }); }); - })(n); - + }(n)); // Select content type. cy.get(`label[data-cy=check-${c}]`).click(); @@ -254,7 +246,7 @@ describe('Campaigns', () => { const plainBody = `hello${n} Demo Subscriber from Bengaluru`; const markdownBody = `**hello${n}** Demo Subscriber from Bengaluru`; - cy.log(`format = ${c}`) + cy.log(`format = ${c}`); if (c === 'richtext') { cy.window().then((win) => { win.tinymce.editors[0].setContent(htmlBody); @@ -262,9 +254,11 @@ describe('Campaigns', () => { }); cy.wait(500); } else if (c === 'html') { - cy.get('code-flask').shadow().find('.codeflask textarea').invoke('val', htmlBody).trigger('input'); + cy.get('code-flask').shadow().find('.codeflask textarea').invoke('val', htmlBody) + .trigger('input'); } else if (c === 'markdown') { - cy.get('textarea[name=content]').invoke('val', markdownBody).trigger('input'); + cy.get('code-flask').shadow().find('.codeflask textarea').invoke('val', markdownBody) + .trigger('input'); } else if (c === 'plain') { cy.get('textarea[name=content]').invoke('val', plainBody).trigger('input'); } @@ -275,7 +269,7 @@ describe('Campaigns', () => { // Preview and match the body. cy.get('button[data-cy=btn-preview]').click(); cy.wait(1000); - cy.get("#iframe").then(($f) => { + cy.get('#iframe').then(($f) => { if (c === 'plain') { return; } diff --git a/frontend/cypress/e2e/forms.cy.js b/frontend/cypress/e2e/forms.cy.js index 1d9a4864..14dfbdb2 100644 --- a/frontend/cypress/e2e/forms.cy.js +++ b/frontend/cypress/e2e/forms.cy.js @@ -3,11 +3,7 @@ const apiUrl = Cypress.env('apiUrl'); describe('Forms', () => { it('Opens forms page', () => { cy.resetDB(); - cy.loginAndVisit('/lists/forms'); - }); - - it('Checks form URL', () => { - cy.get('a[data-cy=url]').contains('http://localhost:9000'); + cy.loginAndVisit('/admin/lists/forms'); }); it('Checks public lists', () => { @@ -70,13 +66,13 @@ describe('Forms', () => { it('Unsubscribes', () => { // Add all lists to the dummy campaign. - cy.request('PUT', `${apiUrl}/api/campaigns/1`, { 'lists': [2] }); + cy.request('PUT', `${apiUrl}/api/campaigns/1`, { lists: [2] }); cy.request('GET', `${apiUrl}/api/subscribers`).then((response) => { - let subUUID = response.body.data.results[0].uuid; + const subUUID = response.body.data.results[0].uuid; cy.request('GET', `${apiUrl}/api/campaigns`).then((response) => { - let campUUID = response.body.data.results[0].uuid; + const campUUID = response.body.data.results[0].uuid; cy.loginAndVisit(`${apiUrl}/subscription/${campUUID}/${subUUID}`); }); }); @@ -110,10 +106,10 @@ describe('Forms', () => { it('Manages subscription preferences', () => { cy.request('GET', `${apiUrl}/api/subscribers`).then((response) => { - let subUUID = response.body.data.results[1].uuid; + const subUUID = response.body.data.results[1].uuid; cy.request('GET', `${apiUrl}/api/campaigns`).then((response) => { - let campUUID = response.body.data.results[0].uuid; + const campUUID = response.body.data.results[0].uuid; cy.loginAndVisit(`${apiUrl}/subscription/${campUUID}/${subUUID}?manage=1`); }); }); @@ -130,5 +126,4 @@ describe('Forms', () => { expect(data.results[1].lists.find((s) => s.id === 3).subscription_status).to.equal('unconfirmed'); }); }); - }); diff --git a/frontend/cypress/e2e/import.cy.js b/frontend/cypress/e2e/import.cy.js index 983d74be..a3f5bdd1 100644 --- a/frontend/cypress/e2e/import.cy.js +++ b/frontend/cypress/e2e/import.cy.js @@ -1,24 +1,31 @@ - describe('Import', () => { it('Opens import page', () => { cy.resetDB(); - cy.loginAndVisit('/subscribers/import'); + cy.loginAndVisit('/admin/subscribers/import'); }); it('Imports subscribers', () => { const cases = [ - { chkMode: 'subscribe', status: 'enabled', chkSubStatus: 'unconfirmed', subStatus: 'unconfirmed', overwrite: true, count: 102 }, - { chkMode: 'subscribe', status: 'enabled', chkSubStatus: 'confirmed', subStatus: 'confirmed', overwrite: true, count: 102 }, - { chkMode: 'subscribe', status: 'enabled', chkSubStatus: 'unconfirmed', subStatus: 'confirmed', overwrite: false, count: 102 }, - { chkMode: 'blocklist', status: 'blocklisted', chkSubStatus: 'unsubscribed', subStatus: 'unsubscribed', overwrite: true, count: 102 }, + { + chkMode: 'subscribe', status: 'enabled', chkSubStatus: 'unconfirmed', subStatus: 'unconfirmed', overwrite: true, count: 102, + }, + { + chkMode: 'subscribe', status: 'enabled', chkSubStatus: 'confirmed', subStatus: 'confirmed', overwrite: true, count: 102, + }, + { + chkMode: 'subscribe', status: 'enabled', chkSubStatus: 'unconfirmed', subStatus: 'confirmed', overwrite: false, count: 102, + }, + { + chkMode: 'blocklist', status: 'blocklisted', chkSubStatus: 'unsubscribed', subStatus: 'unsubscribed', overwrite: false, count: 102, + }, ]; cases.forEach((c) => { cy.get(`[data-cy=check-${c.chkMode}] .check`).click(); cy.get(`[data-cy=check-${c.chkSubStatus}] .check`).click(); - if (!c.overwrite) { - cy.get(`[data-cy=overwrite]`).click(); + if (c.overwrite) { + cy.get('[data-cy=overwrite]').click(); } if (c.status === 'enabled') { @@ -35,28 +42,29 @@ describe('Import', () => { }); cy.get('button.is-primary').click(); + + // ONLY if .modal button.is-primary is present, click it. + if (c.overwrite) { + cy.get('.modal button.is-primary').click(); + } + cy.get('section.wrap .has-text-success'); cy.get('button.is-primary').click(); cy.wait(100); // Verify that 100 (+2 default) subs are imported. - cy.loginAndVisit('/subscribers'); + cy.loginAndVisit('/admin/subscribers'); cy.wait(100); cy.get('[data-cy=count]').then(($el) => { cy.expect(parseInt($el.text().trim())).to.equal(c.count); }); - // Subscriber status. - cy.get('tbody td[data-label=Status]').each(($el) => { - cy.wrap($el).find(`.tag.${c.status}`); - }); - // Subscription status. - cy.get('tbody td[data-label=E-mail]').each(($el) => { - cy.wrap($el).find(`.tag.${c.subStatus}`); - }); + // cy.get('tbody td[data-label=E-mail]').each(($el) => { + // cy.wrap($el).find(`.tag.${c.subStatus}`); + // }); - cy.loginAndVisit('/subscribers/import'); + cy.loginAndVisit('/admin/subscribers/import'); cy.wait(100); }); }); @@ -65,7 +73,7 @@ describe('Import', () => { cy.wait(1000); cy.resetDB(); cy.wait(1000); - cy.loginAndVisit('/subscribers/import'); + cy.loginAndVisit('/admin/subscribers/import'); cy.get('.list-selector input').click(); cy.get('.list-selector .autocomplete a').first().click(); diff --git a/frontend/cypress/e2e/lists.cy.js b/frontend/cypress/e2e/lists.cy.js index ce9e47a9..33c31ff0 100644 --- a/frontend/cypress/e2e/lists.cy.js +++ b/frontend/cypress/e2e/lists.cy.js @@ -1,14 +1,13 @@ describe('Lists', () => { it('Opens lists page', () => { cy.resetDB(); - cy.loginAndVisit('/lists'); + cy.loginAndVisit('/admin/lists'); }); it('Counts subscribers in default lists', () => { cy.get('tbody td[data-label=Subscribers]').contains('1'); }); - it('Creates campaign for list', () => { cy.get('tbody a[data-cy=btn-campaign]').first().click(); cy.location('pathname').should('contain', '/campaigns/new'); @@ -18,7 +17,6 @@ describe('Lists', () => { cy.get('.modal button.is-primary').click(); }); - it('Creates opt-in campaign for list', () => { cy.get('tbody a[data-cy=btn-send-optin-campaign]').click(); cy.get('.modal button.is-primary').click(); @@ -26,10 +24,9 @@ describe('Lists', () => { cy.clickMenu('lists', 'all-lists'); }); - it('Checks individual subscribers in lists', () => { const subs = [{ listID: 1, email: 'john@example.com' }, - { listID: 2, email: 'anon@example.com' }]; + { listID: 2, email: 'anon@example.com' }]; // Click on each list on the lists page, go the subscribers page // for that list, and check the subscriber details. @@ -65,7 +62,6 @@ describe('Lists', () => { }); }); - it('Deletes lists', () => { // Delete all visible lists. cy.get('tbody tr').each(() => { @@ -77,7 +73,6 @@ describe('Lists', () => { cy.get('table tr.is-empty'); }); - // Add new lists. it('Adds new lists', () => { // Open the list form and create lists of multiple type/optin combinations. @@ -108,16 +103,14 @@ describe('Lists', () => { }); }); - it('Searches lists', () => { cy.get('[data-cy=query]').clear().type('list-public-single-2{enter}'); - cy.wait(200) + cy.wait(200); cy.get('tbody tr').its('length').should('eq', 1); cy.get('tbody td[data-label="Name"]').first().contains('list-public-single-2'); cy.get('[data-cy=query]').clear().type('{enter}'); }); - // Sort lists by clicking on various headers. At this point, there should be four // lists with IDs = [3, 4, 5, 6]. Sort the items be columns and match them with // the expected order of IDs. @@ -141,8 +134,8 @@ describe('Lists', () => { cy.get('ul li').its('length').should('eq', 2); const cases = [ - { 'name': 'list-public-single-2', 'description': 'desc-public-2' }, - { 'name': 'list-public-double-3', 'description': 'desc-public-3' } + { name: 'list-public-single-2', description: 'desc-public-2' }, + { name: 'list-public-double-3', description: 'desc-public-3' }, ]; cases.forEach((c, n) => { diff --git a/frontend/cypress/e2e/settings.cy.js b/frontend/cypress/e2e/settings.cy.js index 5e1894c3..82a8a7ad 100644 --- a/frontend/cypress/e2e/settings.cy.js +++ b/frontend/cypress/e2e/settings.cy.js @@ -3,7 +3,7 @@ const apiUrl = Cypress.env('apiUrl'); describe('Templates', () => { it('Opens settings page', () => { cy.resetDB(); - cy.loginAndVisit('/settings'); + cy.loginAndVisit('/admin/settings'); }); it('Changes some settings', () => { diff --git a/frontend/cypress/e2e/subscribers.cy.js b/frontend/cypress/e2e/subscribers.cy.js index ad8ea44b..b51eafe4 100644 --- a/frontend/cypress/e2e/subscribers.cy.js +++ b/frontend/cypress/e2e/subscribers.cy.js @@ -3,15 +3,13 @@ const apiUrl = Cypress.env('apiUrl'); describe('Subscribers', () => { it('Opens subscribers page', () => { cy.resetDB(); - cy.loginAndVisit('/subscribers'); + cy.loginAndVisit('/admin/subscribers'); }); - it('Counts subscribers', () => { - cy.get('tbody td[data-label=Status]').its('length').should('eq', 2); + cy.get('tbody td[data-label=E-mail]').its('length').should('eq', 2); }); - it('Searches subscribers', () => { const cases = [ { value: 'john{enter}', count: 1, contains: 'john@example.com' }, @@ -21,7 +19,7 @@ describe('Subscribers', () => { cases.forEach((c) => { cy.get('[data-cy=search]').clear().type(c.value); - cy.get('tbody td[data-label=Status]').its('length').should('eq', c.count); + cy.get('tbody td[data-label=E-mail]').its('length').should('eq', c.count); if (c.contains) { cy.get('tbody td[data-label=E-mail]').contains(c.contains); } @@ -49,7 +47,6 @@ describe('Subscribers', () => { }); }); - it('Advanced searches subscribers', () => { cy.get('[data-cy=btn-advanced-search]').click(); @@ -62,15 +59,14 @@ describe('Subscribers', () => { cases.forEach((c) => { cy.get('[data-cy=query]').clear().type(c.value); cy.get('[data-cy=btn-query]').click(); - cy.get('tbody td[data-label=Status]').its('length').should('eq', c.count); + cy.get('tbody td[data-label=E-mail]').its('length').should('eq', c.count); }); cy.get('[data-cy=btn-query-reset]').click(); cy.wait(1000); - cy.get('tbody td[data-label=Status]').its('length').should('eq', 2); + cy.get('tbody td[data-label=E-mail]').its('length').should('eq', 2); }); - it('Does bulk subscriber list add and remove', () => { const cases = [ // radio: action to perform, rows: table rows to select and perform on: [expected statuses of those rows after thea action] @@ -82,7 +78,6 @@ describe('Subscribers', () => { { radio: 'check-list-add', lists: [0], rows: { 0: ['unconfirmed', 'unsubscribed'] } }, ]; - cases.forEach((c, n) => { // Select one of the 2 subscribers in the table. Object.keys(c.rows).forEach((r) => { @@ -124,10 +119,9 @@ describe('Subscribers', () => { it('Resets subscribers page', () => { cy.resetDB(); - cy.loginAndVisit('/subscribers'); + cy.loginAndVisit('/admin/subscribers'); }); - it('Edits subscribers', () => { const status = ['enabled', 'blocklisted']; const json = '{"string": "hello", "ints": [1,2,3], "null": null, "sub": {"bool": true}}'; @@ -151,7 +145,10 @@ describe('Subscribers', () => { cy.get('input[name=email]').clear().type(email); cy.get('input[name=name]').clear().type(name); - cy.get('select[name=status]').select(status[n]); + + if (status[n] === 'blocklisted') { + cy.get('select[name=status]').select(status[n]); + } cy.get('.list-selector input').click(); cy.get('.list-selector .autocomplete a').first().click(); cy.get('textarea[name=attribs]').clear().type(json, { parseSpecialCharSequences: false, delay: 0 }); @@ -169,7 +166,10 @@ describe('Subscribers', () => { const id = parseInt(idStr); cy.wrap($el).find('td[data-label=E-mail]').contains(rows[id].email.toLowerCase()); cy.wrap($el).find('td[data-label=Name]').contains(rows[id].name); - cy.wrap($el).find('td[data-label=Status]').contains(rows[id].status, { matchCase: false }); + + if (rows[id].status === 'blocklisted') { + cy.wrap($el).find('[data-cy=blocklisted]'); + } // Both lists on the enabled sub should be 'unconfirmed' and the blocklisted one, 'unsubscribed.' cy.wrap($el).find(`.tags .${rows[id].status === 'enabled' ? 'unconfirmed' : 'unsubscribed'}`) @@ -192,13 +192,11 @@ describe('Subscribers', () => { cy.get('table tr.is-empty'); }); - it('Creates new subscribers', () => { const statuses = ['enabled', 'blocklisted']; const lists = [[1], [2], [1, 2]]; const json = '{"string": "hello", "ints": [1,2,3], "null": null, "sub": {"bool": true}}'; - // Cycle through each status and each list ID combination and create subscribers. const n = 0; for (let n = 0; n < 6; n++) { @@ -225,7 +223,10 @@ describe('Subscribers', () => { const tr = cy.get('tbody tr:nth-child(1)').then(($el) => { cy.wrap($el).find('td[data-label=E-mail]').contains(email.toLowerCase()); cy.wrap($el).find('td[data-label=Name]').contains(name); - cy.wrap($el).find('td[data-label=Status]').contains(status, { matchCase: false }); + + if (status === 'blocklisted') { + cy.wrap($el).find('[data-cy=blocklisted]'); + } cy.wrap($el).find(`.tags .${status === 'enabled' ? 'unconfirmed' : 'unsubscribed'}`) .its('length').should('eq', list.length); cy.wrap($el).find('td[data-label=Lists]').then((l) => { @@ -236,9 +237,9 @@ describe('Subscribers', () => { }); it('Sorts subscribers', () => { - let asc = [3, 4, 5, 6, 7, 8]; - let desc = [8, 7, 6, 5, 4, 3]; - let cases = ['cy-email', 'cy-name', 'cy-created_at', 'cy-updated_at']; + const asc = [3, 4, 5, 6, 7, 8]; + const desc = [8, 7, 6, 5, 4, 3]; + const cases = ['cy-email', 'cy-name', 'cy-created_at', 'cy-updated_at']; cases.forEach((c) => { cy.sortTable(`thead th.${c}`, asc); @@ -246,30 +247,16 @@ describe('Subscribers', () => { cy.sortTable(`thead th.${c}`, desc); cy.wait(250); }); - - - asc = [4, 6, 8, 3, 5, 7]; - desc = [7, 5, 3, 8, 6, 4]; - cases = ['cy-status']; - - cases.forEach((c) => { - cy.sortTable(`thead th.${c}`, asc); - cy.wait(250); - cy.sortTable(`thead th.${c}`, desc); - cy.wait(250); - }); - }); }); - describe('Domain blocklist', () => { it('Opens settings page', () => { cy.resetDB(); }); it('Add domains to blocklist', () => { - cy.loginAndVisit('/settings'); + cy.loginAndVisit('/admin/settings'); cy.get('.b-tabs nav a').eq(2).click(); cy.get('textarea[name="privacy.domain_blocklist"]').clear().type('ban.net\n\nBaN.OrG\n\nban.com\n\n'); cy.get('[data-cy=btn-save]').click(); @@ -287,7 +274,6 @@ describe('Domain blocklist', () => { cy.get('h2').contains('Error'); }); - // Post to the admin API. it('Try via admin API', () => { cy.wait(1000); @@ -330,7 +316,7 @@ describe('Domain blocklist', () => { }); it('Try via import', () => { - cy.loginAndVisit('/subscribers/import'); + cy.loginAndVisit('/admin/subscribers/import'); cy.get('.list-selector input').click(); cy.get('.list-selector .autocomplete a').first().click(); @@ -350,7 +336,7 @@ describe('Domain blocklist', () => { }); it('Clear blocklist and try', () => { - cy.loginAndVisit('/settings'); + cy.loginAndVisit('/admin/settings'); cy.get('.b-tabs nav a').eq(2).click(); cy.get('textarea[name="privacy.domain_blocklist"]').clear(); cy.get('[data-cy=btn-save]').click(); diff --git a/frontend/cypress/e2e/templates.cy.js b/frontend/cypress/e2e/templates.cy.js index f43e7073..374f52c1 100644 --- a/frontend/cypress/e2e/templates.cy.js +++ b/frontend/cypress/e2e/templates.cy.js @@ -1,10 +1,9 @@ describe('Templates', () => { it('Opens templates page', () => { cy.resetDB(); - cy.loginAndVisit('/campaigns/templates'); + cy.loginAndVisit('/admin/campaigns/templates'); }); - it('Counts default templates', () => { cy.get('tbody td[data-label=Name]').should('have.length', 3); }); @@ -27,7 +26,6 @@ describe('Templates', () => { cy.wait(250); }); - // Verify the newly created row. cy.get('tbody td[data-label="Name"]').contains('td', 'cloned tx'); }); @@ -36,14 +34,14 @@ describe('Templates', () => { cy.get('tbody td.actions [data-cy=btn-edit]').first().click(); cy.wait(250); cy.get('input[name=name]').clear().type('edited'); - cy.get('code-flask').shadow().find('.codeflask textarea').invoke('val', 'test {{ template "content" . }}').trigger('input'); + cy.get('code-flask').shadow().find('.codeflask textarea').invoke('val', 'test {{ template "content" . }}') + .trigger('input'); cy.get('.modal-card-foot button.is-primary').click(); cy.wait(250); cy.get('tbody td[data-label="Name"] a').contains('edited'); }); - it('Previews campaign templates', () => { // Edited one sould have a bare body. cy.get('tbody [data-cy=btn-preview').eq(0).click(); @@ -79,15 +77,15 @@ describe('Templates', () => { cy.get('tbody td[data-label="Name"]').contains('td', 'cloned campaign').then((el) => { cy.wrap(el).parent().find('[data-cy=btn-set-default]').click(); cy.get('.modal button.is-primary').click(); - }); // The original default shouldn't have default and the new one should have. - cy.get('tbody').contains('td', 'edited').parent().find('[data-cy=btn-delete]').should('exist'); - cy.get('tbody').contains('td', 'cloned campaign').parent().find('[data-cy=btn-delete]').should('not.exist'); + cy.get('tbody').contains('td', 'edited').parent().find('[data-cy=btn-delete]') + .should('exist'); + cy.get('tbody').contains('td', 'cloned campaign').parent().find('[data-cy=btn-delete]') + .should('not.exist'); }); - it('Deletes template', () => { cy.wait(250); @@ -97,7 +95,7 @@ describe('Templates', () => { cy.get('.modal button.is-primary').click(); }); cy.wait(250); - }) + }); cy.get('tbody td.actions').should('have.length', 3); }); diff --git a/frontend/cypress/support/commands.js b/frontend/cypress/support/commands.js index f9959e4d..8caf1f5c 100644 --- a/frontend/cypress/support/commands.js +++ b/frontend/cypress/support/commands.js @@ -21,12 +21,17 @@ Cypress.Commands.add('sortTable', (theadSelector, ordIDs) => { }); Cypress.Commands.add('loginAndVisit', (url) => { - cy.visit(url, { - auth: { - username: Cypress.env('username'), - password: Cypress.env('password'), - }, - }); + cy.visit(`/admin/login?next=${url}`); + + const username = Cypress.env('LISTMONK_ADMIN_USER') || 'admin'; + const password = Cypress.env('LISTMONK_ADMIN_PASSWORD') || 'listmonk'; + + // Fill the username and passowrd and login. + cy.get('input[name=username]').invoke('val', username); + cy.get('input[name=password]').invoke('val', password); + + // Submit form. + cy.get('button').click(); }); Cypress.Commands.add('clickMenu', (...selectors) => { diff --git a/frontend/package.json b/frontend/package.json index d24959ea..e79b8e78 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -18,7 +18,7 @@ "codeflask": "^1.4.1", "dayjs": "^1.11.10", "indent.js": "^0.3.5", - "prismjs":"^1.29.0", + "prismjs": "^1.29.0", "qs": "^6.10.1", "textversionjs": "^1.1.3", "tinymce": "^5.10.9", @@ -32,7 +32,7 @@ "devDependencies": { "@vitejs/plugin-vue2": "^2.3.1", "@vue/eslint-config-airbnb": "^7.0.1", - "cypress": "13.6.1", + "cypress": "13.15.0", "cypress-file-upload": "^5.0.2", "eslint": "^8.56.0", "eslint-define-config": "^2.0.0", diff --git a/frontend/src/views/Subscribers.vue b/frontend/src/views/Subscribers.vue index 9da70375..f0b60901 100644 --- a/frontend/src/views/Subscribers.vue +++ b/frontend/src/views/Subscribers.vue @@ -103,12 +103,13 @@ - + {{ props.row.email }} - + {{ $t(`subscribers.status.${props.row.status}`) }} diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 673f2979..7588fe52 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -24,10 +24,10 @@ resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== -"@cypress/request@^3.0.0": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@cypress/request/-/request-3.0.1.tgz#72d7d5425236a2413bd3d8bb66d02d9dc3168960" - integrity sha512-TWivJlJi8ZDx2wGOw1dbLuHJKUYX7bWySw377nlnGOW3hP9/MUKIsEdXT/YngWxVdgNCHRBmFlBipE+5/2ZZlQ== +"@cypress/request@^3.0.4": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@cypress/request/-/request-3.0.5.tgz#d893a6e68ce2636c085fcd8d7283c3186499ba63" + integrity sha512-v+XHd9XmWbufxF1/bTaVm2yhbxY+TB4YtWRqF2zaXBlDNMkls34KiATz0AVDLavL3iB6bQk9/7n3oY1EoLSWGA== dependencies: aws-sign2 "~0.7.0" aws4 "^1.8.0" @@ -35,14 +35,14 @@ combined-stream "~1.0.6" extend "~3.0.2" forever-agent "~0.6.1" - form-data "~2.3.2" - http-signature "~1.3.6" + form-data "~4.0.0" + http-signature "~1.4.0" 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" + qs "6.13.0" safe-buffer "^5.1.2" tough-cookie "^4.1.3" tunnel-agent "^0.6.0" @@ -348,13 +348,6 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.3.tgz#f0b991c32cfc6a4e7f3399d6cb4b8cf9a0315014" integrity sha512-p6ua9zBxz5otCmbpb5D3U4B5Nanw6Pk3PPyX05xnxbB/fRv71N7CPmORg7uAD5P70T0xmx1pzAx/FUfa5X+3cw== -"@types/node@^18.17.5": - version "18.19.3" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.3.tgz#e4723c4cb385641d61b983f6fe0b716abd5f8fc0" - integrity sha512-k5fggr14DwAytoA/t8rPrIz++lXK7/DqckthCmoZOKNsEbJkId4Z//BqgApXBUGrGddrigYa1oqheo/7YmW4rg== - dependencies: - undici-types "~5.26.4" - "@types/prismjs@^1.9.1": version "1.26.0" resolved "https://registry.yarnpkg.com/@types/prismjs/-/prismjs-1.26.0.tgz#a1c3809b0ad61c62cac6d4e0c56d610c910b7654" @@ -736,7 +729,7 @@ buffer-crc32@~0.2.3: resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== -buffer@^5.6.0: +buffer@^5.7.1: version "5.7.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== @@ -771,6 +764,17 @@ call-bind@^1.0.4, call-bind@^1.0.5: get-intrinsic "^1.2.1" set-function-length "^1.1.1" +call-bind@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" + integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + set-function-length "^1.2.1" + callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -875,7 +879,7 @@ colorette@^2.0.16: resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== -combined-stream@^1.0.6, combined-stream@^1.0.8, 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" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -931,20 +935,19 @@ cypress-file-upload@^5.0.2: resolved "https://registry.yarnpkg.com/cypress-file-upload/-/cypress-file-upload-5.0.8.tgz#d8824cbeaab798e44be8009769f9a6c9daa1b4a1" integrity sha512-+8VzNabRk3zG6x8f8BWArF/xA/W0VK4IZNx3MV0jFWrJS/qKn8eHfa5nU73P9fOQAgwHFJx7zjg4lwOnljMO8g== -cypress@13.6.1: - version "13.6.1" - resolved "https://registry.yarnpkg.com/cypress/-/cypress-13.6.1.tgz#c5f714f08551666ed3ac1fa95718eabb23a416df" - integrity sha512-k1Wl5PQcA/4UoTffYKKaxA0FJKwg8yenYNYRzLt11CUR0Kln+h7Udne6mdU1cUIdXBDTVZWtmiUjzqGs7/pEpw== +cypress@13.15.0: + version "13.15.0" + resolved "https://registry.yarnpkg.com/cypress/-/cypress-13.15.0.tgz#5eca5387ef34b2e611cfa291967c69c2cd39381d" + integrity sha512-53aO7PwOfi604qzOkCSzNlWquCynLlKE/rmmpSPcziRH6LNfaDUAklQT6WJIsD8ywxlIy+uVZsnTMCCQVd2kTw== dependencies: - "@cypress/request" "^3.0.0" + "@cypress/request" "^3.0.4" "@cypress/xvfb" "^1.2.4" - "@types/node" "^18.17.5" "@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.6.0" + buffer "^5.7.1" cachedir "^2.3.0" chalk "^4.1.0" check-more-types "^2.24.0" @@ -962,7 +965,7 @@ cypress@13.6.1: figures "^3.2.0" fs-extra "^9.1.0" getos "^3.2.1" - is-ci "^3.0.0" + is-ci "^3.0.1" is-installed-globally "~0.4.0" lazy-ass "^1.6.0" listr2 "^3.8.3" @@ -976,7 +979,7 @@ cypress@13.6.1: request-progress "^3.0.0" semver "^7.5.3" supports-color "^8.1.1" - tmp "~0.2.1" + tmp "~0.2.3" untildify "^4.0.0" yauzl "^2.10.0" @@ -1035,6 +1038,15 @@ define-data-property@^1.0.1, define-data-property@^1.1.1: gopd "^1.0.1" has-property-descriptors "^1.0.0" +define-data-property@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" + integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + gopd "^1.0.1" + define-properties@^1.1.3, define-properties@^1.1.4: version "1.2.0" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.0.tgz#52988570670c9eacedd8064f4a990f2405849bd5" @@ -1203,6 +1215,18 @@ es-abstract@^1.22.1: unbox-primitive "^1.0.2" which-typed-array "^1.1.13" +es-define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" + integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== + dependencies: + get-intrinsic "^1.2.4" + +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + es-iterator-helpers@^1.0.12, es-iterator-helpers@^1.0.15: version "1.0.15" resolved "https://registry.yarnpkg.com/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz#bd81d275ac766431d19305923707c3efd9f1ae40" @@ -1692,13 +1716,13 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== +form-data@~4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.1.tgz#ba1076daaaa5bfd7e99c1a6cb02aa0a5cff90d48" + integrity sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw== dependencies: asynckit "^0.4.0" - combined-stream "^1.0.6" + combined-stream "^1.0.8" mime-types "^2.1.12" fs-extra@^9.1.0: @@ -1780,6 +1804,17 @@ get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: has-symbols "^1.0.3" hasown "^2.0.0" +get-intrinsic@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" + integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + get-stream@^5.0.0, get-stream@^5.1.0: version "5.2.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" @@ -1890,6 +1925,13 @@ has-property-descriptors@^1.0.0: dependencies: get-intrinsic "^1.1.1" +has-property-descriptors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" + integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== + dependencies: + es-define-property "^1.0.0" + has-proto@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" @@ -1926,14 +1968,14 @@ he@^1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== -http-signature@~1.3.6: - version "1.3.6" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.3.6.tgz#cb6fbfdf86d1c974f343be94e87f7fc128662cf9" - integrity sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw== +http-signature@~1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.4.0.tgz#dee5a9ba2bf49416abc544abd6d967f6a94c8c3f" + integrity sha512-G5akfn7eKbpDN+8nPS/cb57YeA1jLTVxjpCj7tmm3QKPdyDy7T+qSC40e9ptydSWvkwjSXw1VbkpyEm39ukeAg== dependencies: assert-plus "^1.0.0" jsprim "^2.0.2" - sshpk "^1.14.1" + sshpk "^1.18.0" human-signals@^1.1.1: version "1.1.1" @@ -2048,7 +2090,7 @@ is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== -is-ci@^3.0.0: +is-ci@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.1.tgz#db6ecbed1bd659c43dac0f45661e7674103d1867" integrity sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ== @@ -2756,12 +2798,12 @@ punycode@^2.1.0, punycode@^2.1.1: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== -qs@6.10.4: - version "6.10.4" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.4.tgz#6a3003755add91c0ec9eacdc5f878b034e73f9e7" - integrity sha512-OQiU+C+Ds5qiH91qh/mg0w+8nwQuLjM4F4M/PbmhDOoYehPh+Fb0bDjtR1sOvy7YKxvj28Y/M0PhP5uVX0kB+g== +qs@6.13.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906" + integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg== dependencies: - side-channel "^1.0.4" + side-channel "^1.0.6" qs@^6.10.1: version "6.11.1" @@ -2889,7 +2931,7 @@ rfdc@^1.3.0: resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== -rimraf@^3.0.0, rimraf@^3.0.2: +rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== @@ -2995,6 +3037,18 @@ set-function-length@^1.1.1: gopd "^1.0.1" has-property-descriptors "^1.0.0" +set-function-length@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" + integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== + dependencies: + define-data-property "^1.1.4" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + gopd "^1.0.1" + has-property-descriptors "^1.0.2" + set-function-name@^2.0.0, set-function-name@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.1.tgz#12ce38b7954310b9f61faa12701620a0c882793a" @@ -3025,6 +3079,16 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" +side-channel@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" + integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== + dependencies: + call-bind "^1.0.7" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" + object-inspect "^1.13.1" + signal-exit@^3.0.2: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" @@ -3063,10 +3127,10 @@ source-map@^0.6.1: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -sshpk@^1.14.1: - version "1.17.0" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5" - integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ== +sshpk@^1.18.0: + version "1.18.0" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.18.0.tgz#1663e55cddf4d688b86a46b77f0d5fe363aba028" + integrity sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ== dependencies: asn1 "~0.2.3" assert-plus "^1.0.0" @@ -3222,12 +3286,10 @@ tinymce@^5.10.9: resolved "https://registry.yarnpkg.com/tinymce/-/tinymce-5.10.9.tgz#1dfacb3231c71a688d90ff44a0b3f2e91b3b9edf" integrity sha512-5bkrors87X9LhYX2xq8GgPHrIgJYHl87YNs+kBcjQ5I3CiUgzo/vFcGvT3MZQ9QHsEeYMhYO6a5CLGGffR8hMg== -tmp@~0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" - integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== - dependencies: - rimraf "^3.0.0" +tmp@~0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.3.tgz#eb783cc22bc1e8bebd0671476d46ea4eb32a79ae" + integrity sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w== to-regex-range@^5.0.1: version "5.0.1" @@ -3356,11 +3418,6 @@ unbox-primitive@^1.0.2: has-symbols "^1.0.3" which-boxed-primitive "^1.0.2" -undici-types@~5.26.4: - version "5.26.5" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" - integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== - universalify@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0"