mirror of
https://github.com/knadh/listmonk.git
synced 2025-10-06 05:16:48 +08:00
Fix Cypress tests to work with new auth and other UI changes.
This commit is contained in:
parent
8c07a2a1c4
commit
0f785b7173
14 changed files with 227 additions and 190 deletions
8
frontend/cypress.config.js
vendored
8
frontend/cypress.config.js
vendored
|
@ -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',
|
||||
},
|
||||
})
|
||||
});
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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 = '<strong>hello</strong> \{\{ .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;
|
||||
}
|
||||
|
|
|
@ -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');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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', () => {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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', '<span>test</span> {{ template "content" . }}').trigger('input');
|
||||
cy.get('code-flask').shadow().find('.codeflask textarea').invoke('val', '<span>test</span> {{ 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);
|
||||
});
|
||||
|
|
|
@ -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) => {
|
||||
|
|
4
frontend/package.json
vendored
4
frontend/package.json
vendored
|
@ -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",
|
||||
|
|
|
@ -103,12 +103,13 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<b-table-column v-slot="props" field="email" :label="$t('subscribers.email')" header-class="cy-email" sortable>
|
||||
<b-table-column v-slot="props" field="email" :label="$t('subscribers.email')" header-class="cy-email" sortable
|
||||
:td-attrs="$utils.tdID">
|
||||
<a :href="`/subscribers/${props.row.id}`" @click.prevent="showEditForm(props.row)"
|
||||
:class="{ 'blocklisted': props.row.status === 'blocklisted' }">
|
||||
{{ props.row.email }}
|
||||
</a>
|
||||
<b-tag v-if="props.row.status !== 'enabled'" :class="props.row.status">
|
||||
<b-tag v-if="props.row.status !== 'enabled'" :class="props.row.status" data-cy="blocklisted">
|
||||
{{ $t(`subscribers.status.${props.row.status}`) }}
|
||||
</b-tag>
|
||||
<b-taglist>
|
||||
|
|
171
frontend/yarn.lock
vendored
171
frontend/yarn.lock
vendored
|
@ -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"
|
||||
|
|
Loading…
Add table
Reference in a new issue