@nestjsvn/swagger-sse
Version:
OpenAPI documentation and interactive Swagger UI for NestJS Server-Sent Events endpoints
133 lines (132 loc) • 5.33 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SSETestHelpers = exports.E2ETestSetup = void 0;
const testing_1 = require("@nestjs/testing");
const swagger_1 = require("@nestjs/swagger");
const setup_1 = require("../../ui/setup");
const playwright_1 = require("playwright");
const test_controllers_1 = require("./test-controllers");
class E2ETestSetup {
static async createTestApp(moduleMetadata) {
const moduleFixture = await testing_1.Test.createTestingModule(moduleMetadata).compile();
const app = moduleFixture.createNestApplication();
// Setup CORS for testing
app.enableCors({
origin: true,
credentials: true,
});
const config = new swagger_1.DocumentBuilder()
.setTitle('Test API')
.setDescription('API for E2E testing')
.setVersion('1.0')
.build();
const document = swagger_1.SwaggerModule.createDocument(app, config, {
extraModels: [
test_controllers_1.UserCreatedDto,
test_controllers_1.MessageReceivedDto,
test_controllers_1.NotificationDto,
test_controllers_1.ErrorEventDto,
test_controllers_1.PerformanceMetricDto,
],
});
(0, setup_1.setupSsePlugin)(app, document, 'api-docs');
await app.init();
return app;
}
static async setupBrowser(browserType = 'chromium') {
const browsers = { chromium: playwright_1.chromium, firefox: playwright_1.firefox, webkit: playwright_1.webkit };
return await browsers[browserType].launch({
headless: process.env.CI === 'true',
devtools: process.env.CI !== 'true',
});
}
static async createContext(testName, moduleMetadata, browserType = 'chromium') {
const app = await this.createTestApp(moduleMetadata);
// Start the server on a random available port
await app.listen(0);
const server = app.getHttpServer();
const address = server.address();
const port = typeof address === 'string' ? 3000 : address?.port || 3000;
const browser = await this.setupBrowser(browserType);
const browserContext = await browser.newContext({
hasTouch: true,
isMobile: false,
});
const page = await browserContext.newPage();
// Setup console logging for debugging
page.on('console', (msg) => {
if (process.env.DEBUG_E2E) {
console.log(`[${testName}] Console:`, msg.text());
}
});
// Setup error logging
page.on('pageerror', (error) => {
console.error(`[${testName}] Page Error:`, error);
});
const baseUrl = `http://localhost:${port}`;
const context = {
app,
server,
browser,
page,
baseUrl,
};
this.contexts.set(testName, context);
return context;
}
static async cleanup(testName) {
const context = this.contexts.get(testName);
if (context) {
await context.page?.close();
await context.page?.context()?.close();
await context.browser?.close();
await context.app?.close();
this.contexts.delete(testName);
}
}
static async cleanupAll() {
const cleanupPromises = Array.from(this.contexts.keys()).map(testName => this.cleanup(testName));
await Promise.all(cleanupPromises);
}
}
exports.E2ETestSetup = E2ETestSetup;
E2ETestSetup.contexts = new Map();
class SSETestHelpers {
static async waitForSSEConnection(page, timeout = 5000) {
await page.waitForSelector('[data-testid="sse-status"][data-status="connected"]', {
timeout,
});
}
static async waitForSSEEvents(page, eventCount = 1, timeout = 10000) {
await page.waitForFunction((count) => {
const events = document.querySelectorAll('[data-testid="sse-event"]');
return events.length >= count;
}, eventCount, { timeout });
}
static async getSSEEvents(page) {
return await page.evaluate(() => {
const events = Array.from(document.querySelectorAll('[data-testid="sse-event"]'));
return events.map(event => ({
type: event.getAttribute('data-event-type') ?? '',
data: JSON.parse(event.getAttribute('data-event-data') ?? '{}'),
timestamp: event.getAttribute('data-timestamp') ?? '',
}));
});
}
static async connectToSSE(page) {
await page.click('[data-testid="sse-connect-btn"]');
await this.waitForSSEConnection(page);
}
static async disconnectFromSSE(page) {
await page.click('[data-testid="sse-disconnect-btn"]');
await page.waitForSelector('[data-testid="sse-status"][data-status="disconnected"]');
}
static async clearEventLog(page) {
await page.click('[data-testid="sse-clear-btn"]');
await page.waitForFunction(() => {
const events = document.querySelectorAll('[data-testid="sse-event"]');
return events.length === 0;
});
}
}
exports.SSETestHelpers = SSETestHelpers;