150 lines
5.7 KiB
JavaScript
150 lines
5.7 KiB
JavaScript
import { test, expect } from '@playwright/test';
|
|
import { adminPath, apiPost, cleanupByNames, ensureDataSource } from './helpers.mjs';
|
|
|
|
test('data sources: create + preview + validation failure path', async ({ page, request }) => {
|
|
const uniq = `${Date.now()}_${Math.floor(Math.random() * 100000)}`;
|
|
const dsName = `e2e_ds_${uniq}`;
|
|
|
|
try {
|
|
await page.goto(adminPath('feca-mailshot-data-sources'));
|
|
await expect(page.getByRole('heading', { name: 'Mailshot Data Sources' })).toBeVisible();
|
|
|
|
await page.getByRole('button', { name: 'New Data Source' }).click();
|
|
await page.locator('#ds_name').fill(dsName);
|
|
await page.locator('#ds_dsl').fill('contacts and accounts');
|
|
await page.getByRole('button', { name: /^Create|Save$/ }).first().click();
|
|
|
|
await expect(page.getByRole('cell', { name: dsName })).toBeVisible();
|
|
|
|
const preview = await apiPost(request, 'feca_mailshots_data_sources_api', 'preview', {
|
|
dsl_text: 'contacts and accounts',
|
|
limit: '10'
|
|
});
|
|
expect(preview._httpStatus).toBe(200);
|
|
expect(JSON.stringify(preview)).not.toContain('Duplicate column name');
|
|
|
|
const invalid = await apiPost(request, 'feca_mailshots_data_sources_api', 'validate', {
|
|
dsl_text: 'unknownsource'
|
|
});
|
|
expect(invalid._httpStatus).toBe(200);
|
|
expect(Array.isArray(invalid.errors)).toBeTruthy();
|
|
expect(invalid.errors.join(' | ')).toContain('Unknown source');
|
|
} finally {
|
|
try {
|
|
await cleanupByNames(request, { dataSourceNames: [dsName] });
|
|
} catch {
|
|
// best effort
|
|
}
|
|
}
|
|
});
|
|
|
|
test('data sources: duplicate row action creates editable copy', async ({ page, request }) => {
|
|
const uniq = `${Date.now()}_${Math.floor(Math.random() * 100000)}`;
|
|
const dsName = `e2e_ds_duplicate_${uniq}`;
|
|
const copyName = `Copy of ${dsName}`;
|
|
|
|
try {
|
|
await ensureDataSource(request, dsName, 'contacts and accounts');
|
|
|
|
await page.goto(adminPath('feca-mailshot-data-sources'));
|
|
await expect(page.getByRole('heading', { name: 'Mailshot Data Sources' })).toBeVisible();
|
|
|
|
const row = page.locator('tr', {
|
|
has: page.getByRole('cell', { name: dsName })
|
|
}).first();
|
|
await expect(row).toBeVisible();
|
|
await row.getByRole('button', { name: 'Duplicate' }).click();
|
|
|
|
const copyRow = page.locator('tr', {
|
|
has: page.getByRole('cell', { name: copyName })
|
|
}).first();
|
|
await expect(copyRow).toBeVisible();
|
|
await copyRow.getByRole('link', { name: 'Edit' }).click();
|
|
|
|
await expect(page.locator('#ds-editor-modal')).toBeVisible();
|
|
await expect(page.locator('#ds_name')).toHaveValue(copyName);
|
|
await expect(page.locator('#ds_dsl')).toHaveValue('contacts and accounts');
|
|
} finally {
|
|
try {
|
|
await cleanupByNames(request, { dataSourceNames: [dsName, copyName] });
|
|
} catch {
|
|
// best effort
|
|
}
|
|
}
|
|
});
|
|
|
|
test('data sources: DSL builder round-trip preserves complex representable DSL', async ({ page, request }) => {
|
|
const uniq = `${Date.now()}_${Math.floor(Math.random() * 100000)}`;
|
|
const dsName = `e2e_ds_roundtrip_${uniq}`;
|
|
const dsl =
|
|
"contacts and accounts where fen1-contact and not (primary-contact) and contacts.account_id = accounts.id and contacts.last_name contains 'smith' and accounts.id in (123) and accounts.name starts-with 'St' and accounts.name ends-with 'Ltd' and contacts.phone_1 blank and contacts.account_id != accounts.id";
|
|
|
|
try {
|
|
await ensureDataSource(request, dsName, dsl);
|
|
|
|
await page.goto(adminPath('feca-mailshot-data-sources'));
|
|
await expect(page.getByRole('heading', { name: 'Mailshot Data Sources' })).toBeVisible();
|
|
|
|
const row = page.locator('tr', {
|
|
has: page.getByRole('cell', { name: dsName })
|
|
}).first();
|
|
await expect(row).toBeVisible();
|
|
await row.getByRole('link', { name: 'Edit' }).click();
|
|
|
|
await expect(page.locator('#ds-editor-modal')).toBeVisible();
|
|
await expect(page.locator('#ds_dsl')).toHaveValue(dsl);
|
|
|
|
await page.locator('#ds-build-dsl-open').click();
|
|
await expect(page.locator('#ds-builder-modal')).toBeVisible();
|
|
await expect(page.locator('#ds-builder-output')).toHaveValue(dsl);
|
|
|
|
await page.locator('#ds-builder-apply').click();
|
|
await expect(page.locator('#ds_dsl')).toHaveValue(dsl);
|
|
|
|
await page.locator('#ds-build-dsl-open').click();
|
|
await expect(page.locator('#ds-builder-output')).toHaveValue(dsl);
|
|
} finally {
|
|
try {
|
|
await cleanupByNames(request, { dataSourceNames: [dsName] });
|
|
} catch {
|
|
// best effort
|
|
}
|
|
}
|
|
});
|
|
|
|
test('data sources: DSL builder round-trip preserves FEN built-in filters', async ({ page, request }) => {
|
|
const uniq = `${Date.now()}_${Math.floor(Math.random() * 100000)}`;
|
|
const dsName = `e2e_ds_fen_roundtrip_${uniq}`;
|
|
const dsl =
|
|
'invoices and ads and advertisers where invoice-ids(10, 11) and issue(202605) and selected';
|
|
|
|
try {
|
|
await ensureDataSource(request, dsName, dsl);
|
|
|
|
await page.goto(adminPath('feca-mailshot-data-sources'));
|
|
await expect(page.getByRole('heading', { name: 'Mailshot Data Sources' })).toBeVisible();
|
|
|
|
const row = page.locator('tr', {
|
|
has: page.getByRole('cell', { name: dsName })
|
|
}).first();
|
|
await expect(row).toBeVisible();
|
|
await row.getByRole('link', { name: 'Edit' }).click();
|
|
|
|
await expect(page.locator('#ds-editor-modal')).toBeVisible();
|
|
await expect(page.locator('#ds_dsl')).toHaveValue(dsl);
|
|
|
|
await page.locator('#ds-build-dsl-open').click();
|
|
await expect(page.locator('#ds-builder-modal')).toBeVisible();
|
|
await expect(page.locator('#ds-builder-output')).toHaveValue(dsl);
|
|
|
|
await page.locator('#ds-builder-apply').click();
|
|
await expect(page.locator('#ds_dsl')).toHaveValue(dsl);
|
|
} finally {
|
|
try {
|
|
await cleanupByNames(request, { dataSourceNames: [dsName] });
|
|
} catch {
|
|
// best effort
|
|
}
|
|
}
|
|
});
|