d1ba63d4a4
# Introduction Creating a playwright test, quite granular and verbose that will verify that the post card preview front component is rendered as expected on the tested twenty instance This covers everything e2e from twenty front, front comp renderer, assets cdn rendered redirection etc Style bridge etc ## Note The playwright test setup assumes the application has already been installed once, it's mainly used by the merge queue as a high level front component and logic function ( will be in the same ci ) regression bottleneck The goal isn't for this test to be run locally
130 lines
4.2 KiB
TypeScript
130 lines
4.2 KiB
TypeScript
import { expect, test } from '@playwright/test';
|
|
import * as fs from 'fs';
|
|
import * as path from 'path';
|
|
|
|
import { CARD_TEST_IDS } from '../src/components/card-test-ids';
|
|
|
|
// Seeded postcard record the preview should display.
|
|
const RECORD_ID = process.env.E2E_POSTCARD_RECORD_ID;
|
|
const EXPECTED_NAME = process.env.E2E_POSTCARD_NAME;
|
|
const EXPECTED_STATUS = process.env.E2E_POSTCARD_STATUS;
|
|
const EXPECTED_CONTENT = process.env.E2E_POSTCARD_CONTENT;
|
|
|
|
const STATUS_BADGE_BACKGROUND: Record<string, string> = {
|
|
DRAFT: 'rgb(153, 153, 153)',
|
|
SENT: 'rgb(232, 140, 48)',
|
|
DELIVERED: 'rgb(76, 175, 80)',
|
|
RETURNED: 'rgb(224, 82, 82)',
|
|
};
|
|
|
|
const WORKSPACE_ORIGIN_FILE = path.resolve(
|
|
__dirname,
|
|
'.auth',
|
|
'workspace-origin.txt',
|
|
);
|
|
|
|
const resolveWorkspaceUrl = (): string => {
|
|
const fromEnv = process.env.E2E_WORKSPACE_URL;
|
|
if (fromEnv) {
|
|
return fromEnv.replace(/\/$/, '');
|
|
}
|
|
|
|
try {
|
|
return fs
|
|
.readFileSync(WORKSPACE_ORIGIN_FILE, 'utf8')
|
|
.trim()
|
|
.replace(/\/$/, '');
|
|
} catch {
|
|
return 'http://app.localhost:3001';
|
|
}
|
|
};
|
|
|
|
// Error states rendered by card.front-component.tsx when it cannot authenticate
|
|
// or fetch the record. None of these may appear once the component renders.
|
|
const FALLBACK_TEXTS = [
|
|
'No postcard data',
|
|
'Record not found',
|
|
'No record ID',
|
|
'apiUrl: missing',
|
|
];
|
|
|
|
test.describe('Postcard card front component', () => {
|
|
test.beforeAll(() => {
|
|
if (!RECORD_ID) {
|
|
throw new Error(
|
|
'E2E_POSTCARD_RECORD_ID is required and must point to a seeded postcard record. ' +
|
|
'Ensure the postcard app is installed and a record exists before running this test.',
|
|
);
|
|
}
|
|
});
|
|
|
|
test('renders the postcard name and status badge in the record preview', async ({
|
|
page,
|
|
}) => {
|
|
await page.goto(`${resolveWorkspaceUrl()}/object/postCard/${RECORD_ID}`);
|
|
|
|
const card = page.getByTestId(CARD_TEST_IDS.root);
|
|
await expect(card).toBeVisible();
|
|
|
|
const cardName = card.getByTestId(CARD_TEST_IDS.name);
|
|
const cardStatus = card.getByTestId(CARD_TEST_IDS.status);
|
|
const cardContent = card.getByTestId(CARD_TEST_IDS.content);
|
|
|
|
await expect(cardName).toHaveCount(1);
|
|
await expect(cardStatus).toHaveCount(1);
|
|
await expect(cardContent).toHaveCount(1);
|
|
|
|
if (EXPECTED_NAME) {
|
|
await expect(cardName).toHaveText(EXPECTED_NAME);
|
|
}
|
|
|
|
if (EXPECTED_STATUS) {
|
|
await expect(cardStatus).toHaveText(EXPECTED_STATUS);
|
|
}
|
|
|
|
if (EXPECTED_CONTENT) {
|
|
await expect(cardContent).toHaveText(EXPECTED_CONTENT);
|
|
}
|
|
|
|
// Redundant style assertions: the front component sets every style inline, so
|
|
// verifying the computed styles proves the component's own render + the
|
|
// remote-dom style bridge ran end-to-end (not just that text leaked onto the
|
|
// page). These mirror card.front-component.tsx exactly.
|
|
|
|
// Root container.
|
|
await expect(card).toHaveCSS('padding', '24px');
|
|
|
|
// Name.
|
|
await expect(cardName).toHaveCSS('font-size', '15px');
|
|
await expect(cardName).toHaveCSS('font-weight', '600');
|
|
await expect(cardName).toHaveCSS('color', 'rgb(51, 51, 51)');
|
|
|
|
// Status badge: white text on a status-dependent colored, rounded chip.
|
|
await expect(cardStatus).toHaveCSS('color', 'rgb(255, 255, 255)');
|
|
await expect(cardStatus).toHaveCSS('font-size', '11px');
|
|
await expect(cardStatus).toHaveCSS('font-weight', '600');
|
|
await expect(cardStatus).toHaveCSS('border-radius', '4px');
|
|
await expect(cardStatus).toHaveCSS('padding-top', '2px');
|
|
await expect(cardStatus).toHaveCSS('padding-bottom', '2px');
|
|
await expect(cardStatus).toHaveCSS('padding-left', '8px');
|
|
await expect(cardStatus).toHaveCSS('padding-right', '8px');
|
|
|
|
if (EXPECTED_STATUS && EXPECTED_STATUS in STATUS_BADGE_BACKGROUND) {
|
|
await expect(cardStatus).toHaveCSS(
|
|
'background-color',
|
|
STATUS_BADGE_BACKGROUND[EXPECTED_STATUS],
|
|
);
|
|
}
|
|
|
|
// Content.
|
|
await expect(cardContent).toHaveCSS('font-size', '14px');
|
|
await expect(cardContent).toHaveCSS('color', 'rgb(85, 85, 85)');
|
|
await expect(cardContent).toHaveCSS('margin', '0px');
|
|
await expect(cardContent).toHaveCSS('white-space', 'pre-line');
|
|
|
|
for (const fallback of FALLBACK_TEXTS) {
|
|
await expect(page.getByText(fallback, { exact: false })).toHaveCount(0);
|
|
}
|
|
});
|
|
});
|